Ist Heap eine Tabelle ohne Indizes oder ohne Clustered-Index?


7

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


1
Heap ist ein nützlicher Begriff, da er sich auf die physische Datenstruktur bezieht. Heaps werden geringfügig anders gespeichert als der von SQL Server als Index bezeichnete Index. Die gesamte Clustered / Nonclustered-Terminologie ist etwas umständlich und inkonsistent, aber genau das haben wir.
usr

Antworten:


14

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.indexessehen Sie, dass index_idder 1ein Clustered Index und 0ist ein Heap. Eine Tabelle wird die eine oder andere haben. Es ist nicht möglich, beides zu haben. Nicht gruppierte Indizes beginnen bei index_id2 und steigen von dort aus an. Alle Tabellen haben eine index_id von entweder 0oder 1und 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:

Heaps (Tabellen ohne Clustered-Indizes)


@ JohnSmithSr. Kein Problem. Ich habe gerade einen zweiten Test hinzugefügt, der die Antwort genauer zeigt.
Solomon Rutzky

Ich möchte nur hinzufügen, um den Home Point weiter voranzutreiben, und mir die hervorragenden Clustered Index-Videos von SQL Skills auf TechNet ansehen. Kim Tripp ist eine wichtige Autorität, wenn nicht die Autorität, für SQL-Indizes, und sie bricht sie für Sie gut auf. Kurz gesagt, eine Tabelle ohne CLUSTERED-Index ist ein Heap. Es ist unsortiert. Sie können weiterhin Indizes für einen nicht gruppierten Index mit zusätzlichem Overhead haben. sqlskills.com/sql-server-resources/…
Ali Razeghi

@AliRazeghi Danke, dass du diesen Link hinzugefügt hast. Ich möchte nur in Bezug auf Ihre Aussage " Kim Tripp ist ... die Autorität " klarstellen, dass die einzige wahre Autorität für SQL Server-Informationen SQL Server selbst ist.
Solomon Rutzky

@ JohnSmithSr. Bitte beachten Sie die Klarstellung, die ich gerade zum 2. Absatz hinzugefügt habe. Sie können es leicht auf der Revisionsseite (Revision 6) sehen.
Solomon Rutzky

1
@srutzky Ich frage mich manchmal, ob die Autoren einfach davon ausgehen, dass die Leser wissen, dass sie sich nur auf den Clustered-Index beziehen. Aber dann ist es wirklich ein Kopfschmerz zu erraten, welche Annahmen die Autoren von anderen haben, die ihre Beiträge lesen.
John Smith

1

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.