web-dev-qa-db-fra.com

Deux index à une colonne vs un index à deux colonnes dans MySQL?

Je suis confronté à ce qui suit et je ne sais pas quelle est la meilleure pratique.

Considérez le tableau suivant (qui deviendra grand):

id PK | giver_id FK | recipient_id FK | rendez-vous amoureux

J'utilise InnoDB et d'après ce que je comprends, il crée automatiquement des index pour les deux colonnes de clé étrangère. Cependant, je ferai également beaucoup de requêtes où je dois faire correspondre une combinaison particulière de:

SELECT...WHERE giver_id = x AND recipient_id = t.

Chacune de ces combinaisons sera unique dans le tableau.

Y a-t-il un avantage à ajouter un index à deux colonnes sur ces colonnes, ou les deux index individuels seraient-ils en théorie suffisants/identiques?

97
Tom

Si vous avez deux index à colonne unique, un seul d'entre eux sera utilisé dans votre exemple.

Si vous avez un index avec deux colonnes, la requête peut être plus rapide (vous devez mesurer). Un index à deux colonnes peut également être utilisé comme index à une seule colonne, mais uniquement pour la colonne répertoriée en premier.

Parfois, il peut être utile d'avoir un index sur (A, B) et un autre index sur (B). Cela accélère les requêtes utilisant l'une des colonnes ou les deux, mais utilise bien sûr également plus d'espace disque.

Lors du choix des index, vous devez également tenir compte de l'effet sur l'insertion, la suppression et la mise à jour. Plus d'index = mises à jour plus lentes.

114
Mark Byers

Un indice de couverture comme:

ALTER TABLE your_table ADD INDEX (giver_id, recipient_id);

... signifierait que l'index pourrait être utilisé si une requête faisant référence à giver_id, ou une combinaison de giver_id et recipient_id. Gardez à l'esprit que les critères d'indexation sont basés à l'extrême gauche - une requête se référant uniquement à recipient_id ne serait pas en mesure d'utiliser l'index de couverture dans l'instruction que j'ai fournie.

De plus, MySQL ne peut utiliser qu'un seul index par SELECT, donc un index de couverture serait le meilleur moyen d'optimiser vos requêtes.

26
OMG Ponies

Si l'un des index de clé étrangère est déjà très sélectif, le moteur de base de données doit utiliser celui-ci pour la requête que vous avez spécifiée. La plupart des moteurs de base de données utilisent une sorte d'heuristique pour pouvoir choisir l'index optimal dans cette situation. Si aucun des index n'est très sélectif en soi, il est probablement judicieux d'ajouter l'index construit sur les deux clés, car vous dites que vous utiliserez beaucoup ce type de requête.

Une autre chose à considérer est de savoir si vous pouvez éliminer le champ PK dans ce tableau et définir l'index de clé primaire sur le giver_id et recipient_id des champs. Vous avez dit que la combinaison est unique, donc cela pourrait fonctionner (étant donné beaucoup d'autres conditions auxquelles vous seul pouvez répondre). En règle générale, cependant, je pense que la complexité supplémentaire qui ajoute ne vaut pas la peine.

4
Mark Wilkins

Une autre chose à considérer est que les caractéristiques de performance des deux approches seront basées sur la taille et la cardinalité de l'ensemble de données. Vous pouvez constater que l'index à 2 colonnes ne devient plus performant qu'à un certain seuil de taille de jeu de données, ou exactement le contraire. Rien ne peut remplacer les mesures de performances pour votre scénario exact.

1
Andrew