BOL scheint einen Heap als Tabelle ohne Clustered-Index zu definieren.
Viele Online-Posts scheinen jedoch einen Haufen mit einer Tabelle ohne Indizes gleichzusetzen.
Gibt es eine Subtilität, die mir nicht bewusst ist?
Vielen Dank
BOL scheint einen Heap als Tabelle ohne Clustered-Index zu definieren.
Viele Online-Posts scheinen jedoch einen Haufen mit einer Tabelle ohne Indizes gleichzusetzen.
Gibt es eine Subtilität, die mir nicht bewusst ist?
Vielen Dank
Antworten:
Sie müssen sehr vorsichtig sein, was Sie in den Interwebs lesen ;-) (das gilt natürlich auch für diese Antwort oder so ziemlich alles, aber immer noch). So wie es viele gute Informationen gibt, gibt es auch viele Fehlinformationen (und leider ist dies nicht auf technische Informationen beschränkt). Und die Leute kopieren und fügen ein / reposten / teilen beide. Es ist also gut, die Frage zu stellen :-).
Obwohl BOL einige Fehler aufweist, ist dies in diesem Fall (und in den meisten Fällen) richtig: Ein Heap ist speziell eine Tabelle ohne Clustered-Index. Es hat nichts mit nicht gruppierten Indizes zu tun. Natürlich ist dies könnte ein einfacher Fall von Missverständnis sein , was „ohne jede Art von Indizes einer Tabelle“ in den „Online - Beiträgen“ , da gesagt wird, ist ein Haufen, aber nur , weil, die keine Indizes bedeutet , dass es kein Clustered - Index ist. Wenn diese Beiträge jedoch behaupten, dass eine Tabelle mit nur nicht gruppierten Indizes kein Heap ist, sind sie definitiv falsch.
Wenn man sich anschaut , sys.indexes
sehen Sie, dass index_id
der 1
ein Clustered Index und 0
ist ein Heap. Eine Tabelle wird die eine oder andere haben. Es ist nicht möglich, beides zu haben. Nicht gruppierte Indizes beginnen bei index_id
2 und steigen von dort aus an. Alle Tabellen haben eine index_id von entweder 0
oder 1
und optional eine oder mehrere von index_id
> = 2
.
Sie können dies sogar mit der folgenden Abfrage testen:
SELECT COUNT(*)
FROM sys.indexes si
WHERE si.index_id IN (0, 1)
GROUP BY si.[object_id]
HAVING COUNT(*) > 1;
Es sollte niemals eine Zeile zurückgeben.
Hier ist ein zweiter Test, der noch offensichtlicher ist und es niemandem erlaubt zu spekulieren, dass die Bedingung existieren kann , aber einfach nicht, was ich mit dem obigen Test für möglich halte :
-- DROP TABLE #tmp;
CREATE TABLE #tmp (Col1 INT, Col2 INT);
SELECT * FROM tempdb.sys.indexes si WHERE si.[object_id] = OBJECT_ID(N'tempdb.dbo.#tmp')
-- 1 row; index_id = 0 and type_desc = HEAP
CREATE NONCLUSTERED INDEX [IX_#tmp] ON #tmp (Col2 ASC);
SELECT * FROM tempdb.sys.indexes si WHERE si.[object_id] = OBJECT_ID(N'tempdb.dbo.#tmp')
-- 2 rows; index_id = 0 / HEAP and index_id = 2 / NONCLUSTERED
CREATE CLUSTERED INDEX [CIX_#tmp] ON #tmp (Col1 ASC);
SELECT * FROM tempdb.sys.indexes si WHERE si.[object_id] = OBJECT_ID(N'tempdb.dbo.#tmp')
-- still 2 rows (not 3!!); index_id = 1 / CLUSTERED and index_id = 2 / NONCLUSTERED
Der Punkt dieses zweiten Tests ist, dass die Autorität darüber, was in Bezug auf SQL Server wahr ist und was nicht, immer SQL Server selbst sein wird. Daher ist es wichtig zu testen, ob SQL Server im Wesentlichen die Frage stellt und nicht ein Mensch. Sogar die Experten liegen manchmal falsch, aber SQL Server ist immer korrekt (natürlich in Bezug auf Fragen zu SQL Server).
Auch wenn dies in keiner Weise "Beweis" ist, ist der Titel der folgenden MSDN-Seite ziemlich aussagekräftig:
Srutzky beantwortete die Frage, aber hier ist ein anderes Skript, um sich selbst zu testen:
CREATE TABLE TestForJohn
(TestID int)
CREATE INDEX IX_Test ON TestForJohn
(TestID)
SELECT t.name, i.type_desc
FROM sys.tables t
INNER JOIN sys.indexes i
ON t.object_id = i.object_id
WHERE t.name = 'TestForJohn'
DROP TABLE TestForJohn