Überlappende der Abdeckung und einzelne Indizes in SQL Server
-
08-10-2019 - |
Frage
Ich habe eine Frage in Bezug auf Best Practices für die Indizierung in SQL Server (oder eine beliebige RDBMS für diese Angelegenheit). Nehmen Sie die folgende Tabelle:
ProfileID int
Text nvarchar(50)
ProfileID
ist mit einem Profile
Tisch verbunden. Für jedes Profil muss jeder Text
eindeutig sein. Deshalb habe ich eine primäre Abdeckung Schlüssel auf beiden Spalten. Fein.
Allerdings mag ich auch die obige Tabelle von ProfileID
abfragen können. Also hat ich auch zu einem Index für ProfileID
setzen.
Das bedeutet, dass ich eine überlappende Index haben. Ich weiß nicht, ob dies eine totale Verschwendung ist, da es eine Abdeckung Index bereits ist, oder ob es richtig ist, da die Abdeckung Index wäre ein Hash der beiden Spalten (oder ich bin Mißverständnis Abdeckung Indizes)?
Edit:
habe ich den Index in der Reihenfolge (ProfileID, Text)
. Was, wenn aus Gründen der Argumentation, gab es 3 Spalten A, B und C, die eine Abdeckung Index über alle 3. Würde hatte er nur davon profitieren, wenn wir gegen „A“ abgefragt oder „A, B, und C“, aber nicht "B" oder "C" oder "B und C"?
Lösung
Ein Index für (ProfileID, Text)
(in dieser Reihenfolge) ist ein Index auf ProfileID
auch.
Sie können noch wollen nur einen zusätzlichen Index für ProfileID
erstellen, wenn Sie auf Abfragen mehr SELECT
Leistung möchten, die Text
nicht beteiligt sind.
Dies hat jedoch zwei Nachteile:
-
Die Aufrechterhaltung zwei Indizes erfordert mehr Ressourcen und Leistung von
DML
Abfragen (INSERT
,UPDATE
,DELETE
) leiden -
Wenn Sie Fragen der beiden Typen mischen, beide Indizes den Cache besetzen und es kann mehr Cache-Misses als mit einem einzigen Index.
Es ist kein Problem, wenn Ihre Tabelle klein genug ist, in den Cache passen zusammen mit den beiden Indizes.
Die Abdeckung Index wäre ein Hash der beiden Spalten (oder bin ich Missverständnis Abdeckung Indizes)?
Ein wirklich abdeckenden Index auf diese Weise erstellt werden würde:
CREATE INDEX ix_mytable_profile__text ON mytable (ProfileID) INCLUDE (Text)
Auf diese Weise würde Text
nur in Blattebene Knoten des Index gespeichert werden.
Da Sie jedoch einen UNIQUE
Index benötigen, müssen beide Spalten Teile des Schlüssels sein. Die Knoten sind lexikographisch auf ProfileID
sortiert dann Text
.
habe ich den Index in der Reihenfolge (Profileid, Text). Was, wenn aus Gründen der Argumentation, gab es 3 Spalten A, B und C, die eine Abdeckung Index über alle 3. Würde hatte er nur davon profitieren, wenn wir gegen „A“ abgefragt oder „A, B, und C“, aber nicht "B" oder "C" oder "B und 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).