I en tabell utan ett klustrat index (en heap-tabell) är datasidor inte länkade samman - så att gå igenom sidor kräver en slå upp i Index Allocation Map .
En klustrad tabell har dock sina datasidor länkade i en dubbellänkad lista - gör sekventiella skanningar lite snabbare. Naturligtvis har du i utbyte kostnaderna för att hålla ordning på datasidorna på INSERT
, UPDATE
och DELETE
. En heaptabell kräver dock en andra skrivning till IAM.
Om din fråga har en RANGE
operator (t.ex.:SELECT * FROM TABLE WHERE Id BETWEEN 1 AND 100
), då skulle en klustrad tabell (som är i en garanterad ordning) vara mer effektiv - eftersom den skulle kunna använda indexsidorna för att hitta den eller de relevanta datasidorna. En hög skulle behöva skanna alla rader, eftersom den inte kan förlita sig på beställning.
Och naturligtvis låter ett klustrat index dig göra en CLUSTERED INDEX SEEK, vilket är ganska optimalt för prestanda... en hög utan index skulle alltid resultera i en tabellskanning.
Så:
-
För din exempelfråga där du markerar alla rader är den enda skillnaden den dubbellänkade listan som ett klustrat index upprätthåller. Detta borde göra din klustrade tabell bara lite snabbare än en hög med ett stort antal rader.
-
För en fråga med en
WHERE
klausul som (åtminstone delvis) kan uppfyllas av det klustrade indexet, kommer du ut före på grund av beställningen - så du behöver inte skanna hela tabellen. -
För en fråga som inte tillfredsställs av det klustrade indexet är du ganska jämn...igen, den enda skillnaden är den dubbelt länkade listan för sekventiell skanning. I båda fallen är du suboptimal.
-
För
INSERT
,UPDATE
ochDELETE
en hög kan eller kanske inte vinner. Högen behöver inte upprätthålla ordning, men kräver en andra skrivning till IAM. Jag tror att den relativa prestandaskillnaden skulle vara försumbar, men också ganska databeroende.
Microsoft har en whitepaper som jämför ett klustrat index med ett ekvivalent icke-klustrat index på en heap (inte exakt samma som jag diskuterade ovan, men nära). Deras slutsats är i princip att sätta ett klusterindex på alla tabeller. Jag ska göra mitt bästa för att sammanfatta deras resultat (återigen, observera att de verkligen jämför ett icke-klustrat index med ett klustrat index här - men jag tror att det är relativt jämförbart):
INSERT
prestanda:klustrade index vinner med cirka 3 % på grund av den andra skrivningen som behövs för en hög.UPDATE
prestanda:klustrade index vinner med cirka 8 % på grund av den andra uppslagningen som behövs för en hög.DELETE
prestanda:klustrade index vinner med cirka 18 % på grund av den andra uppslagningen som behövs och den andra raderingen som behövs från IAM för en hög.- enkel
SELECT
prestanda:klustrade index vinner med cirka 16 % på grund av den andra uppslagningen som behövs för en hög. - intervall
SELECT
prestanda:klustrade index vinner med cirka 29 % på grund av den slumpmässiga beställningen för en hög. - samtidigt
INSERT
:högtabell vinner med 30 % under belastning på grund av siddelningar för det klustrade indexet.