Sdílet prostřednictvím


Haldy (tabulky bez clusterovaných indexů)

Platí pro:SQL ServerAzure SQL DatabaseSpravovaná instance Azure SQLDatabáze SQL v Microsoft Fabric

Halda je tabulka bez clusterovaného indexu. Jeden nebo více neclusterovaných indexů lze vytvořit v tabulkách uložených jako haldu. Data jsou uložená na haldě bez zadání pořadí. Obvykle jsou data zpočátku uložena v pořadí, ve kterém jsou řádky vloženy. Databázový stroj ale může přesouvat data v haldě a efektivně ukládat řádky. Ve výsledcích dotazu nelze předpovědět pořadí dat. Pokud chcete zaručit pořadí řádků vrácených z haldy, použijte klauzuli ORDER BY . Pokud chcete zadat trvalé logické pořadí pro ukládání řádků, vytvořte v tabulce clusterovaný index, aby tabulka nebyla haldou.

Note

Někdy existují dobré důvody, proč nechat tabulku jako haldu místo vytváření clusterovaného indexu, ale efektivní využívání hald je dovednost na pokročilé úrovni. Většina tabulek by měla mít pečlivě zvolený clusterovaný index, pokud neexistuje dobrý důvod pro ponechání tabulky jako hromady.

Kdy použít haldu

Halda je ideální pro tabulky, které se často odmazávají a znovu načítají. Databázový stroj optimalizuje prostor v paměťové haldě využitím nejprve dostupného místa.

Vezměte v úvahu následující skutečnosti:

  • Vyhledání volného místa v haldě může být nákladné, zejména pokud došlo k mnoha odstraněním nebo aktualizacím.
  • Clusterované indexy nabízejí stabilní výkon tabulek, které nejsou často zkráceny.

U tabulek, které jsou pravidelně zkráceny nebo znovu vytvořeny, například dočasné nebo pracovní tabulky, je použití haldy často efektivnější.

Volba mezi použitím haldy a clusterovaného indexu může výrazně ovlivnit výkon a efektivitu vaší databáze.

Pokud je tabulka uložená jako halda, jednotlivé řádky jsou identifikovány odkazem na identifikátor 8bajtového řádku (RID), který se skládá z čísla souboru, čísla datové stránky a slotu na stránce (FileID:PageID:SlotID). Řádkové ID je malá a efektivní struktura.

Haldy lze použít jako pracovní tabulky pro velké a neřazené operace vkládání. Protože se data vkládají bez vynucení striktního pořadí, operace vložení je obvykle rychlejší než ekvivalentní vložení do clusterovaného indexu. Pokud se data haldy načtou a zpracují do konečného cíle, může být užitečné vytvořit úzký neclusterovaný index, který pokrývá predikát vyhledávání používaný dotazem.

Note

Data se načítají z haldy v pořadí datových stránek, ale nemusí nutně odpovídat pořadí vložení dat.

Odborníci na data někdy také používají haldy, když se k datům vždy přistupuje prostřednictvím neklastrovaných indexů a identifikátor RID je menší než klíč klastrovaného indexu.

Pokud je tabulka haldou a nemá žádné neclusterované indexy, musí být celá tabulka přečtena (prohledávání tabulky), aby se našel libovolný řádek. SQL Server nemůže vyhledat identifikátor RID přímo na haldě. Toto chování může být přijatelné, pokud je tabulka malá.

Kdy nepoužívat haldu

Nepoužívejte haldu, pokud se data často vrací v seřazeném pořadí. Clusterovaný index ve sloupci řazení by se mohl vyhnout operaci řazení.

Nepoužívejte haldu, pokud jsou data často seskupována dohromady. Data musí být seřazena před seskupením a clusterovaný index ve sloupci řazení by se mohl vyhnout operaci řazení.

Nepoužívejte datovou hromadu, pokud jsou rozsahy dat často dotazovány z tabulky. Skupinový index ve sloupci rozsahu zabraňuje řazení celé haldy.

Nepoužívejte haldu, pokud nejsou k dispozici žádné neclusterované indexy a tabulka je velká. Jedinou aplikací pro tento návrh je vrácení celého obsahu tabulky bez zadaného pořadí. V haldě načte databázový engine všechny řádky, aby našel jakýkoli řádek.

Nepoužívejte haldu, pokud se data často aktualizují. Pokud aktualizujete záznam a aktualizace používá více místa na datových stránkách, než aktuálně používají, musí být záznam přesunut na datovou stránku, která má dostatek volného místa. Tím se vytvoří přeposlaný záznam odkazující na nové umístění dat a ukazatel pro předávání musí být zapsán na stránce, která tato data držela dříve, aby bylo možné označit nové fyzické umístění. Přináší to fragmentaci haldy. Když databázový stroj prohledá haldu, řídí se těmito ukazateli. Tato akce omezuje výkon čtení dopředu a může vést k dodatečným vstupně-výstupním operacím, což snižuje výkon skenování.

Správa hald

Pokud chcete vytvořit haldu, vytvořte tabulku bez clusterovaného indexu. Pokud už tabulka obsahuje clusterovaný index, zahoďte clusterovaný index, aby se tabulka vrátila do haldy.

Pokud chcete haldu odebrat, vytvořte v haldě clusterovaný index.

Opětovné sestavení haldy pro uvolnění nevyužitého prostoru:

  • Vytvořte clusterovaný index v haldě a pak tento clusterovaný index vypusťte.
  • Pro opětovné sestavení haldy použijte příkaz ALTER TABLE ... REBUILD.

Warning

Vytvoření nebo vyřazení clusterovaných indexů vyžaduje přepsání celé tabulky. Pokud tabulka obsahuje neclusterované indexy, musí se všechny neclusterované indexy znovu vytvořit při každé změně clusterovaného indexu. Změna z haldy na strukturu clusterovaného indexu nebo zpět proto může trvat hodně času a vyžadovat místo na disku pro změnu pořadí dat v databázi tempdb.

Identifikujte haldy

Následující dotaz vrátí seznam hald z aktuální databáze. Seznam obsahuje:

  • Názvy tabulek
  • Názvy schématu
  • Počet řádků
  • Velikost tabulky v kB
  • Velikost indexu v kB
  • Nevyužité místo
  • Sloupec pro identifikaci haldy
SELECT t.name AS 'Your TableName',
    s.name AS 'Your SchemaName',
    p.rows AS 'Number of Rows in Your Table',
    SUM(a.total_pages) * 8 AS 'Total Space of Your Table (KB)',
    SUM(a.used_pages) * 8 AS 'Used Space of Your Table (KB)',
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS 'Unused Space of Your Table (KB)',
    CASE 
        WHEN i.index_id = 0
            THEN 'Yes'
        ELSE 'No'
        END AS 'Is Your Table a Heap?'
FROM sys.tables t
INNER JOIN sys.indexes i
    ON t.object_id = i.object_id
INNER JOIN sys.partitions p
    ON i.object_id = p.object_id
        AND i.index_id = p.index_id
INNER JOIN sys.allocation_units a
    ON p.partition_id = a.container_id
LEFT JOIN sys.schemas s
    ON t.schema_id = s.schema_id
WHERE i.index_id <= 1 -- 0 for Heap, 1 for Clustered Index
GROUP BY t.name,
    s.name,
    i.index_id,
    p.rows
ORDER BY 'Your TableName';

Struktury haldy

Halda je tabulka bez clusterovaného indexu. V sys.partitions mají haldy jeden řádek pro každý oddíl index_id = 0 používaný haldou. Ve výchozím nastavení má halda jeden oddíl. Pokud halda obsahuje více oddílů, každý oddíl má strukturu haldy, která obsahuje data pro daný oddíl. Pokud má například halda čtyři oddíly, existují čtyři struktury haldy; jeden v každém oddílu.

Podle datových typů v haldě bude mít každá struktura haldy jednu nebo více jednotek přidělení k ukládání a správě dat pro konkrétní oddíl. Každá halda bude mít minimálně jednu IN_ROW_DATA alokační jednotku na oddíl. Halda bude mít také jednu LOB_DATA alokační jednotku na oddíl, pokud obsahuje velké sloupce objektu (LOB). Pokud obsahuje sloupce s proměnlivou délkou, které překračují limit velikosti 8 060 bajtů, bude mít také jednu ROW_OVERFLOW_DATA alokační jednotku na oddíl.

Sloupec first_iam_page v systémovém zobrazení sys.system_internals_allocation_units odkazuje na první stránku IAM v řetězu stránek IAM, které spravují prostor přidělený haldě v určitém oddílu. SQL Server používá stránky IAM k procházení haldového úložiště. Datové stránky a řádky v nich nejsou v žádném konkrétním pořadí a nejsou propojené. Jediným logickým propojením mezi datovými stránkami jsou informace zaznamenané na stránkách IAM.

Important

Systémové sys.system_internals_allocation_units zobrazení je vyhrazeno pouze pro interní použití SQL Serveru. Budoucí kompatibilita není zaručena.

Prohledávání tabulek nebo sériové čtení haldy lze provést skenováním stránek IAM za účelem nalezení rozsahů, které obsahují stránky haldy. Vzhledem k tomu, že IAM představuje rozsahy ve stejném pořadí, v jakém existují v datových souborech, znamená to, že sekvenční hromadné skeny procházejí sekvenčně každý soubor. Použití stránek IAM k nastavení sekvence skenování také znamená, že řádky z haldy se obvykle nevracejí v pořadí, ve kterém byly vloženy.

Následující obrázek ukazuje, jak databázový stroj SQL Serveru používá stránky IAM k načtení řádků dat v haldě jednoho oddílu.

iam_heap

VYTVOŘTE INDEX (Transact-SQL)
DROP INDEX (Transact-SQL)
clusterované a neclusterované indexy popsané