2010-03-23 18 views

Répondre

2

Lorsque vous voulez la vitesse de récupération maximale et ont deux colonnes dans la jointure ou lorsque les conditions, mais parfois la colonne une a une plus grande sélectivité et parfois colonne b a une plus grande sélectivité, et vous voulez tirer parti de ce fait à partir d'un index unique.

Aussi je pense que votre rapport de taille de données/performance de la machine devrait être assez haut et en même temps vous devrez estimer n'importe quelle amélioration une nécessité (même si seulement de quelques pourcentages) . Pourtant, l'expérience enseigne que les choses dépendent de beaucoup de facteurs; Avec des environnements de SGBDR et d'applications spécifiques, vous feriez mieux de gérer vos propres tests.

EDIT: Explication supplémentaire sur les index composites. "L'ordre dans lequel les colonnes sont répertoriées dans la définition de l'index est important: il est possible de récupérer un ensemble d'identifiants de ligne en utilisant uniquement la première colonne indexée, mais ce n'est pas possible ou efficace (sur la plupart des Par exemple, imaginez un annuaire téléphonique qui est organisé par ville d'abord, puis par nom de famille, puis par prénom, si vous avez reçu le nom de la base de données. Vous pouvez facilement extraire la liste de tous les numéros de téléphone de cette ville, mais dans ce répertoire, il serait très fastidieux de trouver tous les numéros de téléphone pour un nom de famille donné. entrées avec ce nom de famille. " Les explications de Wikipedia sont peut-être trop simplifiées, mais elles vous donnent l'idée de base (comme les analogies vont garder à l'esprit que les annuaires téléphoniques ont généralement des index clusterisés et ce ne serait pas votre index général de base de données). En fonction de la taille de l'index par rapport à la taille de la structure de données par rapport à la mémoire disponible par rapport à la sélectivité sur la première colonne de l'index, il peut être beaucoup moins coûteux d'utiliser l'index erroné. Imaginez un bon manuel, il aurait une table des matières avec des chapitres et sous-chapitre et le nombre de pages où ils se trouvent (ce qui est un non index clusterisé qui contient des pointeurs vers des enregistrements de données - pages). Maintenant, imaginez que le manuel est sur la norme SQL-92, alors la plupart des termes dans TOC seraient des termes SQL (maintenez cette hypothèse). Vous auriez également un autre index à la fin du livre qui énumérerait tous les termes intéressants dans les ordres alphabétiques (supposons avec les principaux noms de chapitre) et les numéros de page.

Pour une question telle que 'Dites-moi tous les chapitres sous lesquels DISTINCT apparaît' vous utiliseriez le second index. (parce que la sélectivité du champ plus tard est élevé)

Pour la question, comme « Dites-moi le nombre des termes qui apparaissent sous le premier chapitre » vous devez utiliser la table des matières

Donc, pour des questions telles que 'SELECT est-il décrit sous le chapitre DML?' vous pourriez utiliser l'un ou l'autre des index. (parce que la sélectivité des deux champs est élevée) Cependant, si la TOC de DML elle-même est de 3 pages et que l'entrée SELECT dans l'index n'a que quinze lignes, vous passerez probablement à la seconde. à partir des deux index. Maintenant, si vous pensez que c'est trop poussé, prenez en considération une base de données de la bibliothèque scannée du congrès. :)

Comme je l'ai déjà dit, toute la planification est bien, mais à la fin, faites vos propres benchmarks.

+0

+1: Bonne explication. N'hésitez pas à up-voter ma réponse aussi - au cas où vous êtes d'accord :) –

1

Je ne pense pas qu'il y ait un cas réel où vous en avez besoin.

Il pourrait avoir un sens quand votre table a beaucoup plus de colonnes, a et b ne sont pas uniques, et vous avez besoin de hautes performances avec les deux requêtes suivantes:

Select Max(b) From t Where a=1 --# Would use i_t_a_b 

et

Select Max(a) From t Where b=1 --# Would use i_t_b_a 

Supposons que votre table ressemble à ceci:

a b c d e 
- - - - - 
0 8 x x x 
0 9 x x x 
1 8 x x x 
1 9 x x x 

i_t_a_b ressemble à quelque chose comme ceci:

0 
    8 
    9 
1 
    8 
    9 

i_t_b_a ressemble à quelque chose comme ceci:

8 
    0 
    1 
9 
    0 
    1 

Select Max(b) From t Where a=1 

aurait à creuser dans 8 et 9 de i_t_b_a pour trouver toutes les lignes avec a=1. C'est encore beaucoup plus rapide qu'une analyse de table complète (devoir lire tous les x aussi), mais ce n'est pas aussi rapide que d'utiliser i_t_a_b.

+0

J'ai fait un test et trouver i_t_a_b peut également être utilisé pour 'b = 1' et vice versa – symfony

+0

@symfony: oui, il peut être utilisé, c'est mieux Ensuite, faire un balayage complet de la table, mais pour b = 1 i_t_b_a fonctionne mieux alors i_t_a_b – Unreason

+0

Pouvez-vous donner une analyse à ce sujet? Bien intuitivement, cela semble raisonnable – symfony