Domanda

Ho una domanda riguardante best practice per l'indicizzazione in SQL Server (o qualsiasi RDBMS per quella materia). Prendere la seguente tabella:

ProfileID int
Text      nvarchar(50)

ProfileID si aggiunge a un tavolo Profile. Per ogni profilo, ogni Text deve essere univoco. Quindi ho messo una chiave primaria di copertura su entrambe le colonne. Bene.

Tuttavia, voglio anche essere in grado di interrogare la tabella di cui sopra per ProfileID. Così ho anche messo un indice su ProfileID troppo.

Questo significa che hanno un indice di sovrapposizione. Non so se questo è uno spreco totale in quanto non v'è un indice di copertura già, o se è corretta in quanto l'indice di copertura sarebbe un hash delle due colonne (o sto equivoco indici di copertura)?

Modifica:

Ho creato l'indice nella (ProfileID, Text) ordine. Che cosa succede se, per ipotesi, ci sono stati 3 colonne A, B, e C, che ha avuto un indice di copertura su tutto 3. Sarebbe beneficio solo se abbiamo chiesto contro "A" o "A, B, e C", ma non "B" o "C", o "B e C"?

È stato utile?

Soluzione

Un indice su (ProfileID, Text) (in questo ordine) è un indice su ProfileID pure.

Si può ancora voglia di creare un indice aggiuntivo sul ProfileID solo, se si desidera una maggiore prestazioni SELECT su query che non comportano Text.

Tuttavia, questo presenta due inconvenienti:

  1. Il mantenimento di due indici richiede più risorse e prestazioni delle query DML (INSERT, UPDATE, DELETE) possono soffrire

  2. Se si mescolano le query dei due tipi, entrambi gli indici si occupano della cache e non ci possono essere più cache miss che con un unico indice.

    Non è un problema se il tavolo è abbastanza piccolo per adattarsi nella cache con entrambi gli indici.

  

L'indice di copertura sarebbe un hash delle due colonne (o sto fraintendendo gli indici di copertura)?

Un indice che copre veramente si verrebbe a creare in questo modo:

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

In questo modo, Text verrebbe memorizzata solo nei nodi livello foglia dell'indice.

Tuttavia, in quanto è necessario un indice UNIQUE, entrambe le colonne devono essere le parti della chiave. I nodi sono ordinati lexicographically su ProfileID quindi Text.

  

Ho creato l'indice nell'ordine (ProfileId, testo). Che cosa succede se, per ipotesi, ci sono stati 3 colonne A, B, e C, che ha avuto un indice di copertura su tutto 3. Sarebbe beneficio solo se abbiamo chiesto contro "A" o "A, B, e C", ma non "B" o "C", o "B e 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).
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top