MySQL - pourquoi ne pas indexer chaque champ?

107

Récemment, j'ai appris la merveille des index et les performances se sont considérablement améliorées. Cependant, avec tout ce que j'ai appris, je n'arrive pas à trouver la réponse à cette question.

Les index sont excellents, mais pourquoi quelqu'un ne pourrait-il pas simplement indexer tous les champs pour rendre la table incroyablement rapide? Je suis sûr qu'il y a une bonne raison de ne pas faire cela, mais qu'en est-il de trois champs dans une table à trente champs? 10 dans un champ de 30? Où doit-on tracer la ligne et pourquoi?

Vael Victus
la source
7
essayez d'insérer une valeur dans une table avec plus de 10k entrées qui sont indexées, toutes les entrées doivent être mises à jour en raison des insertions / suppressions et c'est une surcharge de temps énorme et un peu de surcharge de mémoire si chaque valeur a un index
Jesus Ramos
5
Il y a une autre raison en plus de l'espace et des performances d'écriture: l'utilisation de plusieurs index pour un accès à une seule table est très inefficace . Cela signifie que même si vous avez un index sur chaque colonne, les performances de la sélection ne sont pas très bonnes si plusieurs colonnes sont accessibles dans la clause WHERE. Dans ce cas, un index multi-colonnes est préférable.
Markus Winand le
1
si vous avez une table avec 30 champs, vous devriez vraiment regarder vos structures de table. Il devrait être très difficile de travailler avec eux.
webs

Réponses:

122

Les index occupent de l'espace en mémoire (RAM); Trop ou trop grand d'index et la base de données va devoir les échanger vers et depuis le disque. Ils augmentent également le temps d'insertion et de suppression (chaque index doit être mis à jour pour chaque élément de données inséré / supprimé / mis à jour).

Vous n'avez pas de mémoire infinie. Faire en sorte que tous les index tiennent dans la RAM = bon.

Vous n'avez pas de temps infini. L'indexation uniquement des colonnes dont vous avez besoin pour l'indexation minimise l'atteinte des performances d'insertion / suppression / mise à jour.

Brian Roach
la source
11
Belle réponse informelle pour donner une compréhension générale, mais pas beaucoup d'aide pour déterminer où tracer la ligne sur les index. Comment peux-tu savoir? Ajoutez-les simplement aux champs couramment WHERED et espérez le meilleur?
Andrew
@Andrew un an et demi plus tard, avez-vous trouvé la réponse à votre question?
Sinjai
1
@Sinjai Les ajouter à des colonnes généralement where'd est probablement une bonne règle de base. Mais sinon, vous pourriez faire beaucoup de lecture, il s'avère que si vous voulez devenir un expert des indices. par exemple. stackoverflow.com/questions/3049283/…
Andrew
N'oubliez pas l'espace disque.
jpmc26
27

Gardez à l'esprit que chaque index doit être mis à jour chaque fois qu'une ligne est mise à jour, insérée ou supprimée. Ainsi, plus vous avez d'index, plus les performances seront lentes pour les opérations d'écriture.

En outre, chaque index occupe davantage d'espace disque et d'espace mémoire (lorsqu'il est appelé), ce qui peut également ralentir les opérations de lecture (pour les grandes tables). Regarde ça

AndyMac
la source
6
Le lien est pour MS SQL Server ; cette question est pour MySQL
OMG Ponies
5
@OMG la plupart des points du lien s'appliquent à tous les principaux SGBDR
RichardTheKiwi
5
@Richard aka cyberkiwi: Les index ne sont pas couverts par l'ANSI - c'est un miracle que chaque fournisseur ait utilisé une terminologie similaire. Mais même dans ce cas, seuls SQL Server et MySQL utilisent la terminologie «clustered» et «non-clustered» index - cela signifie plus dans SQL Server que MySQL. Rien ne garantit que les recommandations d'un fournisseur doivent être appliquées à un autre.
OMG Ponies
3
@omg les 6 premiers points s'appliquent à tous les dbms. ignorez les non / clustered, puis ci-dessous sont plus de points concernant l'indexation générale, également sur le point. Si vous souhaitez signaler des choses spécifiques, appelez-les. Sinon, il semble que vous annulez toutes les réponses qui, d'après les commentaires (y compris votre réponse supprimée), que personne n'est d'accord avec votre évaluation.
RichardTheKiwi
10

Vous devez équilibrer les besoins de CRUD. L'écriture dans les tableaux devient lente. Quant à savoir où tracer la ligne, cela dépend de la façon dont les données sont accédées (tri, filtrage, etc.).

Smandoli
la source
et aussi chaque index prend de l'espace dans la base de données
Acanthus
@Acanthus: Les plus petits disques durs disponibles sont mesurés en gigaoctets .
OMG Ponies
4
@OMG mais pas RAM comme le souligne Brian. ce n'est jamais une bonne idée de stocker plus que nécessaire. la mise en cache des données / index dans la RAM, les supports de sauvegarde (versions adaptées à chaque bande, etc.) sont tous effectués par des index inutiles
RichardTheKiwi
9
L'abondance d'une ressource n'est pas une raison de gaspillage ou d'inefficacité.
Smandoli
6
C'est vrai, mais les contraintes ne sont pas ce qu'elles étaient il y a plus de 10 ans.
OMG Ponies
2

L'indexation occupera plus d'espace alloué à la fois du lecteur et de la RAM, mais améliorera également considérablement les performances. Malheureusement, lorsqu'il atteint la limite de mémoire, le système restitue l'espace disque et risque les performances. En pratique, vous ne devriez indexer aucun champ qui, selon vous, n'implique aucun type d'algorithme de traversée de données, ni insertion ni recherche (clause WHERE). Mais vous devriez dans le cas contraire. Par défaut, vous devez indexer tous les champs. Les champs que vous devriez envisager de désindexer sont les suivants: si les requêtes sont utilisées uniquement par le modérateur, sauf si elles ont également besoin de vitesse

Lionel Jerinho
la source
2

cette réponse est basée sur mon opinion personnelle J'utilise ma logique mathématique pour répondre

la deuxième question portait sur la frontière où s'arrêter, commençons par faire un calcul mathématique, supposons que nous ayons N lignes avec L champs dans une table si nous indexons tous les champs, nous obtiendrons un L nouvelles tables d'index où chaque table triera dans un manière significative les données du champ d'index, à première vue si votre table est un poids W cela deviendra W * 2 (1 tera deviendra 2 tera) si vous avez 100 grande table (j'ai déjà travaillé dans un projet où le numéro de table était autour de 1800 table) vous gaspillerez 100 fois cet espace (100 téra), c'est loin d'être sage.

Si nous appliquons des index dans toutes les tables, nous devrons penser aux mises à jour d'index si un déclencheur de mise à jour, tous les index sont mis à jour, il s'agit d'une sélection de tous les équivalents non ordonnés dans le temps

à partir de là je conclus que vous avez dans ce scénario que si vous perdez ce temps est préférable de le perdre dans une sélection ni une mise à jour car si vous sélectionnez un champ qui n'est pas indexé vous ne déclencherez pas une autre sélection sur tous les champs qui sont non indexé

quoi indexer?

clés étrangères: est un must basé sur

clé primaire: je ne sais pas encore si quelqu'un a lu ceci pourrait aider dans ce cas

autres champs: la première réponse naturelle est la moitié des champs restants pourquoi: si vous devez indexer plus vous n'êtes pas loin de la meilleure réponse si vous devez moins indexer vous n'êtes pas aussi loin car nous savons qu'aucun index n'est mauvais et que tout est indexé est également mauvais.

à partir de ces 3 points, je peux conclure que si nous avons L champs composés de K clés, la limite devrait être quelque part ((L-K)/2)+Kplus ou moins proche de L / 10

cette réponse est basée sur ma logique et mes prictices personnels

Mohammed Housseyn Taleb
la source
1

Ce n'est pas une bonne idée d'indexer toutes les colonnes d'une table. Bien que cela rende la table très rapide à lire, elle devient également beaucoup plus lente à écrire. L'écriture dans une table dont chaque colonne est indexée impliquerait de placer le nouvel enregistrement dans cette table, puis de placer les informations de chaque colonne dans sa propre table d'index.

Rachid Sakara
la source
Je ne sais pas si cela rendrait la lecture de la table ultra rapide, surtout si la table de données ne fait que 100 Mo mais que l'index.table 300 Mo ou plus.
David
Tout ce que vous avez dit a déjà été dit.
Vael Victus