web-dev-qa-db-fra.com

Quelles colonnes font généralement de bons index?

Pour faire suite à " Que sont les index et comment puis-je les utiliser pour optimiser les requêtes dans ma base de données? " où j'essaie d'en savoir plus sur les index, quelles colonnes sont de bons candidats d'index? Spécifiquement pour une base de données MS SQL?

Après quelques recherches sur Google, tout ce que j'ai lu suggère que les colonnes qui sont généralement croissantes et uniques font un bon index (des choses comme l'auto_increment de MySQL), je comprends cela, mais j'utilise MS SQL et j'utilise des GUID pour les clés primaires, donc il semble que les index ne bénéficieraient pas GUID colonnes ...

85
mmattax

Les index peuvent jouer un rôle important dans l'optimisation des requêtes et la recherche rapide des résultats à partir des tables. Il est donc très important de sélectionner les colonnes à indexer. Il existe deux principaux endroits où nous pouvons envisager l'indexation: les colonnes référencées dans la clause WHERE et les colonnes utilisées dans les clauses JOIN. En bref, ces colonnes doivent être indexées par rapport auxquelles vous devez rechercher des enregistrements particuliers. Supposons que nous ayons une table nommée acheteurs où la requête SELECT utilise des index comme ci-dessous:

SELECT
 buyer_id /* no need to index */
FROM buyers
WHERE first_name='Tariq' /* consider to use index */
AND last_name='Iqbal'   /* consider to use index */

Puisque "Buyer_id" est référencé dans la partie SELECT, MySQL ne l'utilisera pas pour limiter les lignes choisies. Il n'y a donc pas grand besoin de l'indexer. Ce qui suit est un autre exemple peu différent de celui ci-dessus:

SELECT
 buyers.buyer_id, /* no need to index */
 country.name    /* no need to index */
FROM buyers LEFT JOIN country
ON buyers.country_id=country.country_id /* consider to use index */
WHERE
 first_name='Tariq' /* consider to use index */
AND
 last_name='Iqbal' /* consider to use index */

Selon les requêtes ci-dessus first_name, les colonnes last_name peuvent être indexées car elles se trouvent dans la clause WHERE. Un champ supplémentaire, country_id de la table country, peut également être pris en compte pour l'indexation car il se trouve dans une clause JOIN. L'indexation peut donc être envisagée sur chaque champ de la clause WHERE ou d'une clause JOIN.

La liste suivante propose également quelques conseils que vous devez toujours garder à l'esprit lorsque vous avez l'intention de créer des index dans vos tables:

  • Indexez uniquement les colonnes requises dans les clauses WHERE et ORDER BY. L'indexation des colonnes en abondance entraînera certains inconvénients.
  • Essayez de profiter de la fonction "préfixe d'index" ou "index multi-colonnes" de MySQL. Si vous créez un index tel que INDEX (prénom, nom), ne créez pas INDEX (prénom). Cependant, "préfixe d'index" ou "index multi-colonnes" n'est pas recommandé dans tous les cas de recherche.
  • Utilisez l'attribut NOT NULL pour les colonnes dans lesquelles vous envisagez l'indexation, afin que les valeurs NULL ne soient jamais stockées.
  • Utilisez l'option --log-long-format pour consigner les requêtes qui n'utilisent pas d'index. De cette façon, vous pouvez examiner ce fichier journal et ajuster vos requêtes en conséquence.
  • L'instruction EXPLAIN vous aide à révéler comment MySQL exécutera une requête. Il montre comment et dans quel ordre les tables sont jointes. Cela peut être très utile pour déterminer comment écrire des requêtes optimisées et si les colonnes doivent être indexées.

Mise à jour (23 février 2015):

Tout index (bon/mauvais) augmente le temps d'insertion et de mise à jour.

En fonction de vos index (nombre d'index et type), le résultat est recherché. Si votre temps de recherche va augmenter à cause de l'index, c'est un mauvais index.

Probablement dans n'importe quel livre, "Page d'index" pourrait avoir une page de début de chapitre, un numéro de page de sujet commence, ainsi qu'une page de sous-sujet commence. Quelques éclaircissements dans la page Index sont utiles mais un index plus détaillé peut vous embrouiller ou vous faire peur. Les index ont également de la mémoire.

La sélection de l'indice doit être judicieuse. Gardez à l'esprit que toutes les colonnes ne nécessitent pas d'index.

90
Somnath Muluk

Certaines personnes ont répondu à une question similaire ici: Comment savez-vous ce qu'est un bon indice?

Fondamentalement, cela dépend vraiment de la façon dont vous interrogerez vos données. Vous voulez un index qui identifie rapidement un petit sous-ensemble de votre ensemble de données qui est pertinent pour une requête. Si vous n'interrogez jamais par horodatage, vous n'avez pas besoin d'index dessus, même s'il est principalement unique. Si tout ce que vous faites est d'obtenir des événements qui se sont produits dans une certaine plage de dates, vous en voulez certainement un. Dans la plupart des cas, un indice sur le sexe est inutile - mais si tout ce que vous faites est d'obtenir des statistiques sur tous les hommes, et séparément, sur toutes les femmes, cela peut valoir la peine d'en créer un. Déterminez quels seront vos modèles de requête et accédez à quel paramètre réduit le plus l'espace de recherche, et c'est votre meilleur index.

Tenez également compte du type d'index que vous créez - les arbres B sont bons pour la plupart des choses et autorisent les requêtes de plage, mais les index de hachage vous permettent d'aller droit au but (mais n'autorisez pas les plages). D'autres types d'index ont d'autres avantages et inconvénients.

Bonne chance!

18
SquareCog

Tout dépend des requêtes que vous vous attendez à poser sur les tables. Si vous demandez toutes les lignes avec une certaine valeur pour la colonne X, vous devrez effectuer une analyse complète de la table si un index ne peut pas être utilisé.

Les index seront utiles si:

  • La ou les colonnes ont un haut degré d'unicité
  • Vous devez souvent rechercher une certaine valeur ou plage de valeurs pour la colonne.

Ils ne seront pas utiles si:

  • Vous sélectionnez un grand% (> 10-20%) des lignes du tableau
  • L'utilisation d'espace supplémentaire est un problème
  • Vous souhaitez maximiser les performances de l'insert. Chaque index d'une table réduit les performances d'insertion et de mise à jour car ils doivent être mis à jour à chaque fois que les données changent.

Les colonnes de clé primaire sont généralement idéales pour l'indexation car elles sont uniques et sont souvent utilisées pour rechercher des lignes.

6
Plasmer

En général (je n'utilise pas mssql donc je ne peux pas commenter spécifiquement), les clés primaires font de bons index. Ils sont uniques et doivent avoir une valeur spécifiée. (De plus, les clés primaires font de si bons index qu'ils ont normalement un index créé automatiquement.)

Un index est en fait une copie de la colonne qui a été triée pour permettre la recherche binaire (ce qui est beaucoup plus rapide que la recherche linéaire). Les systèmes de base de données peuvent utiliser diverses astuces pour accélérer encore plus la recherche, en particulier si les données sont plus complexes qu'un simple nombre.

Ma suggestion serait de ne pas utiliser d'index au départ et de profiler vos requêtes. Si une requête particulière (telle que la recherche de personnes par nom de famille, par exemple) est exécutée très souvent, essayez à nouveau de créer un index sur les attributs et le profil pertinents. S'il y a une accélération notable sur les requêtes et un ralentissement négligeable sur les insertions et les mises à jour, conservez l'index.

(Je m'excuse si je répète les choses mentionnées dans votre autre question, je ne les avais pas rencontrées auparavant.)

5
Zooba

Toute colonne qui sera régulièrement utilisée pour extraire des données de la table doit être indexée.

Cela comprend: les clés étrangères -

select * from tblOrder where status_id=:v_outstanding

champs descriptifs -

select * from tblCust where Surname like "O'Brian%"

Les colonnes n'ont pas besoin d'être uniques. En fait, vous pouvez obtenir de très bonnes performances à partir d'un index binaire lors de la recherche d'exceptions.

select * from tblOrder where paidYN='N'
4
pappes

Une colonne GUID n'est pas le meilleur candidat pour l'indexation. Les index sont mieux adaptés aux colonnes avec un type de données qui peut recevoir un ordre significatif, c'est-à-dire trié (entier, date, etc.).

Peu importe si les données d'une colonne augmentent généralement. Si vous créez un index sur la colonne, l'index créera sa propre structure de données qui référencera simplement les éléments réels dans votre table sans se soucier de l'ordre stocké (un index non cluster). Ensuite, par exemple, une recherche binaire peut être effectuée sur votre structure de données d'index pour permettre une récupération rapide.

Il est également possible de créer un "index clusterisé" qui réorganisera physiquement vos données. Cependant, vous ne pouvez en avoir qu'un par table, alors que vous pouvez avoir plusieurs index non clusterisés.

3
Ash

Cela dépend vraiment de vos requêtes. Par exemple, si vous écrivez presque uniquement dans une table, il est préférable de ne pas avoir d'index, ils ralentissent simplement les écritures et ne sont jamais utilisés. Toute colonne que vous utilisez pour joindre une autre table est un bon candidat pour un index.

Lisez également la fonctionnalité des index manquants. Il surveille les requêtes réelles utilisées par rapport à votre base de données et peut vous dire quels index auraient amélioré les performances.

3
jwanagel

Votre clé primaire doit toujours être un index. (En fait, je serais surpris qu'il ne soit pas automatiquement indexé par MS SQL.) Vous devriez également indexer fréquemment les colonnes SELECT ou ORDER; leur objectif est à la fois une recherche rapide d'une valeur unique et un tri plus rapide.

Le seul véritable danger dans l'indexation de too de nombreuses colonnes est de ralentir les modifications apportées aux lignes dans les grandes tables, car les index doivent également tous être mis à jour. Si vous ne savez vraiment pas quoi indexer, chronométrez simplement vos requêtes les plus lentes, regardez quelles colonnes sont utilisées le plus souvent et indexez-les. Voyez ensuite à quel point ils sont plus rapides.

1
Eevee

Les types de données numériques qui sont classés par ordre croissant ou décroissant sont de bons index pour plusieurs raisons. Premièrement, les nombres sont généralement plus rapides à évaluer que les chaînes (varchar, char, nvarchar, etc.). Deuxièmement, si vos valeurs ne sont pas ordonnées, les lignes et/ou les pages peuvent avoir besoin d'être mélangées pour mettre à jour votre index. C'est des frais généraux supplémentaires.

Si vous utilisez SQL Server 2005 et que vous utilisez des identificateurs uniques (GUID) et que vous n'avez PAS besoin qu'ils soient de nature aléatoire, consultez le type séquentiel uniqueidentifier.

Enfin, si vous parlez d'index clusterisés, vous parlez du type de données physiques. Si vous avez une chaîne comme index cluster, cela pourrait devenir moche.

1
Ian Suttle

Cela devrait être encore plus rapide si vous utilisez un GUID. Supposons que vous ayez les enregistrements

  1. 100
  2. 200
  3. 3000
  4. ....

Si vous avez un index (recherche binaire, vous pouvez trouver l'emplacement physique de l'enregistrement que vous recherchez en temps O (lg n), au lieu de rechercher séquentiellement O(n) temps. c'est parce que vous ne savez pas quels enregistrements vous avez dans votre table.

0
Milhous

La règle d'or était les colonnes qui sont beaucoup utilisées dans les clauses WHERE, ORDER BY et GROUP BY, ou celles qui semblaient être utilisées fréquemment dans les jointures. Gardez à l'esprit que je fais référence aux index, PAS à la clé primaire

Ne pas donner de réponse "vanille", mais cela dépend vraiment de la façon dont vous accédez aux données

0
curtisk

Le meilleur index dépend du contenu de la table et de ce que vous essayez d'accomplir.

Prenons un exemple Une base de données de membres avec une clé primaire du numéro de sécurité sociale des membres. Nous choisissons le S.S. parce que le priamry d'application fait référence à l'individu de cette façon, mais vous voulez également créer une fonction de recherche qui utilisera le nom et le prénom des membres. Je suggérerais alors de créer un index sur ces deux champs.

Vous devez d'abord savoir quelles données vous allez interroger, puis déterminer quelles données vous avez besoin d'indexer.

0
Joseph