Je suis confronté à ce qui suit et je ne suis pas sûr de la meilleure pratique.
Considérez le tableau suivant (qui deviendra grand):
id PK | giver_id FK | destinataire_id FK | Date
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 vais également faire beaucoup de requêtes dans lesquelles 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?
Réponses:
Si vous avez deux index à une seule colonne, 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 un index de colonne unique, 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 ou les deux colonnes, 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.
la source
Un index de couverture comme:
... signifierait que l'index pourrait être utilisé si une requête référencée
giver_id
ou une combinaison degiver_id
etrecipient_id
. Gardez à l'esprit que les critères d'index sont basés à l'extrême gauche - une requête faisant référence uniquement nerecipient_id
pourrait pas utiliser l'index de couverture dans la déclaration 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.
la source
MySQL can only use one index per SELECT
ce n'est plus vrai, ce serait bien si vous éditiez votre réponse pour qu'elle soit mise à jour.recipient_id
?INDEX (col1, col2, col3, col4)
alors l'index sera appliqué pour les recherches avec uneWHERE
clause commecol1 = 'A'
oucol1 = 'A' AND col2 = 'B'
oucol1 = 'A' AND col2 ='B' AND col3 = 'C' AND col4 = 'D'
, mais cet index particulier ne sera pas utilisé pour quelque chose commeWHERE col2 = 'B'
ouWHERE col3 = 'C' AND col4 = 'D'
parce que les champs de recherche ne sont pas les plus laissés dans la définition d'index. Vous devrez ajouter des index supplémentaires pour couvrir ces champs.Si l'un des index de clé étrangère est déjà très sélectif, le moteur de base de données doit l'utiliser 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 deux 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 de cette table et définir l'index de clé primaire sur les champs
giver_id
etrecipient_id
. Vous avez dit que la combinaison est unique, donc cela fonctionnerait probablement (étant donné de nombreuses 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.la source
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 constaterez peut-être 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.
la source