2009-09-30 5 views
0

J'ai une table MySQL (InnoDB) « éléments » avec les caractéristiques suivantesL'avantage de la performance dans ce modèle de données?

  1. Un grand nombre de lignes, et ne cesse d'augmenter.
  2. Grand nombre de colonnes de différents types de données, y compris 'text';
  3. La clé primaire 'item_id' est présente.

Il y a des exigences supplémentaires suivantes:

  1. besoin d'interroger les éléments en fonction de leur statut
  2. besoin de mettre à jour le statut

Les deux opérations se produisent assez fréquemment au-dessus.

Étant donné le scénario ci-dessus, j'ai deux questions

  1. Would faisant une table séparée avec deux colonnes et à savoir item_idstatus avec item_id comme clé primaire offrent une plus grande performance?
  2. Si ce qui précède est vrai, comment puis-je m'attaquer aux éléments item_ids en fonction du statut?

Je n'ai aucune expérience dans la gestion de bases de données. J'espère que vous supporterez avec moi :)

Répondre

3

Ceci est appelé segmentation verticale. Il est souvent utilisé lorsqu'une entité de données a plusieurs modèles d'accès qui accèdent à différents sous-ensembles des attributs d'entités (colonnes de table), avec des fréquences différentes. Si une fonction n'a besoin d'accéder qu'à une ou deux colonnes 100 fois par seconde, et qu'une autre fonction d'application a besoin d'accéder à toutes les autres colonnes, mais seulement une ou deux fois par jour, cette approche est justifiée et amènera une amélioration substantielle de la performance. Fondamentalement, comme vous l'avez suggéré, vous "divisez" la table en deux tables, les deux avec la même clé, avec une relation un à un FK/PK-> PK. Dans un tableau, vous ne mettez que les quelques colonnes auxquelles vous accédez plus fréquemment, et vous placez le reste des colonnes dans l'autre table qui sera accessible moins fréquemment.Vous pouvez ensuite appliquer l'indexation à chaque table de manière plus appropriée en fonction du modèle d'accès réel pour chaque table séparément.

+0

Merci pour la réponse. – nano

1

Il serait plus logique de créer un index sur votre statut et votre item_id si c'est les seules colonnes que vous devez chercher.

create index status_item_id_items on items (status) 

Vous pouvez alors interroger votre résultat qui utilisera cet indice:

select item_id, status from items where status = 'status' 

Gardez à l'esprit que si vous n'avez pas beaucoup de différents statuts de votre mai de requête finit par revenir un grand nombre de lignes et pourrait être lent. Si vous pouvez être contraint par une colonne plus "sélective" comme un datetime, ce serait mieux.

+0

Merci Vincent. Mais si j'indexe à la fois item_id et status, la mise à jour des valeurs d'état ne serait-elle pas plus lente à mesure que la taille de la table augmente? Ou ne serait-il pas important car il n'a que deux colonnes? – nano

+0

Pour mettre à jour une ligne à la fois, ce qui est probablement votre cas d'utilisation, cela devrait être négligeable. C'est vrai que vous avez un autre index à mettre à jour, mais créer une nouvelle table coûterait beaucoup plus cher. – Vincent

+0

Merci. Vraiment apprécier votre aide. – nano

0

Répondre à la partie 2 d'abord, vous feriez une jointure de vos deux tables:

SELECT i.*, s.StatusCode FROM items AS i INNER JOIN status AS s ON s.item_id = i.item_id 

Pour répondre à la partie 1, cependant, je ne pense pas faire cela vous gagner un avantage de performance.

Questions connexes