Que signifie «index» sur les SGBDR? [fermé]

21

J'utilise des index comme la plupart des développeurs (principalement sur ... eh bien! Index), mais je suis sûr qu'il existe de nombreuses façons subtiles d'optimiser une base de données à l'aide d'index. Je ne sais pas si c'est spécifique à une implémentation d'un SGBD.

Ma question est: quels sont les bons exemples d'utilisation de l'index (à l'exception des cas basiques et évidents), et comment un SGBD optimise-t-il sa base de données lorsque vous spécifiez un index sur une table?

Thomas Joulin
la source
En réfléchissant davantage à cette question, cette question est trop générale pour ce site. Si nous modifions la portée de la question qui pourrait être appropriée, sinon cette question n'est pas appropriée pour le site.
jcolebrand
J'aime expliquer les index en utilisant la métaphore de la bibliothèque mysqlperformanceblog.com/2011/08/30/… Voyez si cela aide ..
Jonathan

Réponses:

11

Considérez un index comme une "table des matières" ... c'est-à-dire une liste ordonnée de pointeurs vers des positions dans un fichier, aussi appelés décalages. Supposons que vous ayez des millions d'enregistrements stockés dans une table, plutôt que de rechercher dans la table des critères de correspondance, il est beaucoup plus rapide de référencer une liste ordonnée pour les correspondances, puis d'empiler les pointeurs sur les lignes correspondantes spécifiques. Un exemple parfait d'un index est un champ de clé primaire de tables, le plus souvent son champ "id". Si vous voulez l'ID de ligne # 11234566, il est beaucoup plus rapide de demander à l'index un pointeur sur les données que de scanner la source de données pour la position 11234566.

Voici une utilisation moins évidente de l'indexation:

CREATE TABLE activity_log (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
activity_type_id SMALLINT UNSIGNED NOT NULL,
datetime_created DATETIME
KEY(activity_type_id),
PRIMARY KEY(id)
);
CREATE TABLE activity_log_to_date_key (
activity_log_id INT UNSIGNED NOT NULL,
date_created_key  INT UNSIGNED NOT NULL REFERENCES dim_datetime(id),
UNIQUE KEY(activity_log_id),
KEY(date_created_key)
);
CREATE TABLE dim_datetime (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
date_hour DATETIME NOT NULL,
PRIMARY KEY(id),
KEY(date_hour)
);

Votre opération peut créer votre enregistrement de journal, mais ensuite créer une référence à un datetime indexé qui est plus rapide à rechercher / trier que votre table de journal. Rejoignez ensuite votre table de journal sur sa propre clé primaire. Si vous avez besoin de moi pour développer cela, faites le moi savoir. J'espère que cela a du sens.

Exemple de requête:

SELECT a.activity_log_id, al.activity_type_id, al.datetime_created
FROM activity_log_to_date_key a 
INNER JOIN dim_datetime d ON (d.id = a.date_created_key)
LEFT JOIN activity_log al ON (al.id = a.activity_log_id)
WHERE d.date_hour BETWEEN '2009-01-01 00:00:00' AND '2009-06-01 12:00:00';
randomx
la source
merci, c'est très clair! Dans votre exemple, "PRIMARY" changera-t-il la façon dont le RDMBS stocke le "décalage", ou est-il simplement utilisé pour des contraintes d'unicité?
Thomas Joulin
9

Un point que beaucoup de gens semblent manquer est qu'un SGBD n'utilisera souvent (ou ne peut que) qu'un seul index par référence de table dans une requête, et s'il peut et utilise plusieurs index, il serait probablement plus rapide d'utiliser un combiné index si présent.

Par exemple, si vous recherchez une grande table pour des lignes, WHERE AnIntegerColumn = 42 AND AnOtherInt = 69l'itinéraire le plus rapide vers ces lignes serait un index sur les deux colonnes AnIntegerColumn et AnOtherInt. Si vous n'avez qu'un index sur chacun individuellement mais aucun index combiné, la base de données recherchera l'un ou l'autre index et filtrera séparément les résultats avec la deuxième clause, ou analysera les deux et mariera les résultats par la suite.

Une autre opération simple courante qui peut être améliorée avec des index composites est la suivante WHERE SomeColumn = <SomeValue> ORDER BY SomeOtherColumn: s'il existe un index sur SomeColumn et SomeOtherColumn (dans le bon ordre), les opérations de filtrage et de classement peuvent être effectuées en même temps dans certaines circonstances.

Ajouter trop d'index peut être une mauvaise optimisation bien sûr, car l'espace supplémentaire utilisé pour stocker les index (et la charge d'E / S pour les maintenir si votre base de données voit de nombreuses opérations d'écriture) peut être un problème pire que les requêtes de lecture légèrement moins optimales , alors ne le faites pas trop.

David Spillett
la source
2

David et Randy ont couvert cela. Je voulais juste ajouter que la EXPLAINcommande peut être d'une grande aide pour déterminer quand vous obtiendrez une grande économie de création d'un index, ainsi que pour suggérer les index nécessaires. Il affichera les étapes que la base de données prend pour exécuter votre requête, afin que vous sachiez quels bits prennent le plus de temps.

Gaurav
la source
Pour ajouter à la réponse de Gaurav, utilisez "EXPLAIN EXTENDED", puis tapez immédiatement "SHOW WARNINGS" pour voir comment votre requête est traduite.
randomx
1

Quelque chose que je n'ai pas encore vu mentionné ici est que lorsque vous avez plus d'un disque, vous voulez probablement placer votre index sur un disque différent de celui où les données se trouvent réellement. Cela peut accélérer certaines opérations. Je pense que cela mérite une question à part entière.

jcolebrand
la source
C'était vrai, mais ces jours-ci, nous disons n'essayez pas de deviner votre sous-système d'E / S. De toute façon, vous ne savez pas où une baie de stockage va placer vos données.
Gaius
1
@gaius Je voulais plutôt dire si vous n'aviez pas de configuration RAID5 (ou similaire), pour mettre les index sur E :, les données sur F :, etc.
jcolebrand