Question

J'ai une question concernant les meilleures pratiques pour l'indexation dans SQL Server (ou tout SGBDR pour cette matière). Prenez le tableau suivant:

ProfileID int
Text      nvarchar(50)

ProfileID est relié à une table de Profile. Pour chaque profil, chaque Text doit être unique. Par conséquent, je mets une clé de couverture primaire sur les deux colonnes. Très bien.

Cependant, je veux aussi pouvoir interroger le tableau ci-dessus par ProfileID. Donc, je mets aussi un index sur ProfileID aussi.

Cela signifie que je possède un indice qui se chevauchent. Je ne sais pas si cela est une perte totale, car il y a un indice de couverture déjà, ou si elle est correcte, puisque l'indice de couverture serait un hachage des deux colonnes (ou je comprends mal les indices de couverture)?

Edit:

J'ai créé l'indice dans l'ordre (ProfileID, Text). Et si, pour l'amour de la discussion, il y avait 3 colonnes A, B et C, qui avait un indice de couverture sur l'ensemble 3. Ne serait-il bénéficier que si nous avons demandé contre « A » ou « A, B et C », mais pas "B" ou "C" ou "B et C"?

Était-ce utile?

La solution

Un index sur (ProfileID, Text) (dans cet ordre) est un index sur ProfileID aussi.

Vous pouvez toujours vouloir créer un index supplémentaire sur ProfileID uniquement, si vous voulez plus de performances SELECT sur les requêtes qui ne concernent pas Text.

Cependant, cela a deux inconvénients:

  1. Le maintien de deux indices nécessite plus de ressources et les performances des requêtes DML (INSERT, UPDATE, DELETE) peuvent souffrir

  2. Si vous mélangez les requêtes des deux types, les deux index occuperont le cache et il peut y avoir plus d'erreurs de cache que d'un seul indice.

    Il est pas un problème si votre table est assez petit pour tenir dans le cache ainsi que les deux indices.

  

L'indice de couverture serait un hachage des deux colonnes (ou je comprends mal les indices de couverture)?

Un indice vraiment couvrant serait créé de cette façon:

CREATE INDEX ix_mytable_profile__text ON mytable (ProfileID) INCLUDE (Text)

De cette façon, Text serait uniquement stocké dans des noeuds de niveau feuille de l'indice.

Cependant, étant donné que vous avez besoin d'un indice de UNIQUE, les deux colonnes doivent être parties de la clé. Les noeuds sont triés sur lexicographique ProfileID puis Text.

  

J'ai créé l'indice dans l'ordre (ProfileID, texte). Et si, pour l'amour de la discussion, il y avait 3 colonnes A, B et C, qui avait un indice de couverture sur l'ensemble 3. Ne serait-il bénéficier que si nous avons demandé contre « A » ou « A, B et C », mais pas "B" ou "C" ou "B et C"?

CREATE INDEX ix_mytable_a_b_c ON mytable (a, b, c)

SELECT  a, b, с
FROM    mytable
WHERE   a = 1 

-- Index lookup, no table lookup. a is leading

SELECT  a, b, с
FROM    mytable
WHERE   a = 1
        AND b = 1

-- Index lookup, no table lookup. (a, b) are leading.

SELECT  a, b, с
FROM    mytable
WHERE   b = 1

-- Index full scan (`b` is not leading), no table lookup

SELECT  a, b, с
FROM    mytable
WHERE   c = 1

-- Index full scan (`c` is not leading), no table lookup

SELECT  a, b, с, d
FROM    mytable
WHERE   a = 1

-- Index lookup, table tookup (d is not a part of the index).

SELECT  a, b, с, d
FROM    mytable
WHERE   b = 1

-- Table full scan (there is no point in using index at all, neither for lookup nor for covering).
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top