Automatická kompaktace indexu (náhled)

Applies to:Azure SQL DatabaseAzure SQL Managed InstanceAUTDSQL v databázi Microsoft Fabric

Automatické komprimace indexů pomáhá snížit spotřebu místa na úložišti, vstupně-výstupních operací disku, procesoru, paměti a zlepšení výkonu úloh, aniž byste museli investovat čas a úsilí do úloh údržby indexů. Komprimace indexu se provádí nepřetržitě a s nízkou režií při změnách dat v databázi.

Poznámka:

Automatická komprimace indexů je aktuálně v náhledu v Azure SQL Database, Azure SQL Managed Instance s vždy aktuální zásadou aktualizace a SQL databází ve Fabric.

Odpovědi na běžné otázky najdete v tématu Nejčastější dotazy.

Povolení a zakázání

Automatické komprimace indexu je ve výchozím nastavení zakázaná. Můžete ji povolit nebo zakázat pro databázi spuštěním následujících příkazů Transact-SQL.

  • Povolení automatické komprimace indexu:

    ALTER DATABASE [database-name-placeholder]
    SET AUTOMATIC_INDEX_COMPACTION = ON;
    
  • Zakažte automatické komprimace indexu:

    ALTER DATABASE [database-name-placeholder]
    SET AUTOMATIC_INDEX_COMPACTION = OFF;
    

Pokud chcete zjistit, jestli je povolená automatická komprimace indexu, použijte zobrazení katalogu sys.databases . Pokud například chcete zjistit, které databáze mají povolenou automatickou komprimci indexu, spusťte následující dotaz:

SELECT database_id,
       name,
       is_automatic_index_compaction_on
FROM sys.databases;

Ke kontrole vlastnosti můžete také použít funkci IsAutomaticIndexCompactionOn.

Výhody a důležité informace

Automatické komprimace indexu poskytuje následující výhody:

  • Nemusíte nastavovat a udržovat úlohy údržby indexů.
  • Zabraňuje vysoké spotřebě prostředků při úlohách údržby indexu.
  • Snižuje růst prostoru, ke kterému může dojít při úpravě dat v databázi.
  • Zlepšuje výkon dotazů.
    • Dotaz, který čte kompaktní index, čte méně stránek, a proto vyžaduje méně vstupně-výstupních operací disku, procesoru a paměti.
    • Pro zlepšení plánu dotazů bude pravděpodobně vybrán kompaktní index.

Důležité

Automatické komprimace funguje pouze na nedávno upravených stránkách. V důsledku toho je režie komprimace minimální v porovnání s opětovným sestavením indexu nebo reorganizací indexu, která zpracovává všechny stránky.

I když je režie procesu komprimace minimální, není nulová. Pokud povolíte automatické komprimace indexu, zvažte následující:

  • Pokud proces komprimace přesune mnoho řádků, může se zobrazit zvýšení množství vstupně-výstupních operací zápisu transakčního protokolu a velikost záloh transakčních protokolů.
  • Při komprimování můžete zaznamenat malý nárůst využití procesoru v rámci nízkého rozsahu jednociferného procenta. Toto zvýšení není běžné.
  • Podobně jako při přeuspořádání indexu proces komprimace získá krátkodobé výhradní (X) zámky stránek k přesunu řádků z jedné stránky na druhou.
    • Dopad souběžnosti je minimální. Pokud se zámek na stránce nedá získat okamžitě, stránka se přeskočí, aby neblokovala jiné dotazy a procesy.
      • Dotazy můžou občas zažít krátkodobé blokování (v řádu milisekund). K tomuto blokování dochází v případě, že se dotaz pokusí získat stránku nebo zámek řádku po tom, co proces komprimace už získal exkluzivní krátkodobý zámek na stránce, a není běžné.

Jak to funguje

Automatická komprimace indexu je součástí procesu čištění úložiště trvalých verzí, které běží na pozadí (PVS). Tento proces pravidelně odebírá zastaralé verze řádků z datových stránek. Pokud pro databázi povolíte automatické komprimace indexů, zkomprimuje indexy také čistič PVS.

Když čistič navštíví každou stránku s nedávno vloženými, aktualizovanými nebo odstraněnými řádky, zkontroluje, jestli má aktuální stránka k dispozici volné místo, s výjimkou volného místa rezervovaného faktorem výplně. Pokud ano, čistič přesune řádky z další stránky na aktuální stránku, pokud se vejdou do volného místa. Tento proces pak přejde dopředu a zopakuje se u malého počtu po sobě jdoucích párů stránek po vyčištění stránky.

Pokud se stránka po přesunutí řádků vyprázdní, uvolní se. V důsledku toho se celkový počet použitých stránek v databázi sníží, zvýší se hustota stránek a sníží se spotřeba místa na úložišti, vstupně-výstupní operace disku, procesoru a paměti fondu vyrovnávací paměti.

Následující diagram znázorňuje koncepční zobrazení datových stránek v indexu před a po komprimování.

Diagram znázorňující koncepční zobrazení datových stránek před a po automatickém komprimování indexu

Proces komprimace pokračuje na pozadí, protože se mění data a zastaralé verze řádků se vyčistí.

Proces komprimace může některé stránky přeskočit kvůli souběžné aktivitě, například:

  • Aktivní transakce pomocí stránky.
  • Probíhá sestavení nebo změna uspořádání indexu.
  • Probíhá operace zmenšení.
  • Velká velikost PVS nebo velký počet přerušených transakcí k vyčištění z PVS.
    • Čištění PVS má přednost před automatickou kompresí. Komprimace je pozastavena, pokud je velikost PVS 150 GB nebo větší nebo pokud je počet přerušených transakcí 1 000 nebo vyšší.

Méně běžné důvody, proč proces komprimace může přeskočit stránky, naleznete v tématu Použití rozšířené události ke sledování statistik komprimace.

Pokud se stránka přeskočí, považuje se za komprimace při příštím zpracování čističem PVS.

Automatické komprimace indexu není k dispozici pro systémové tabulky a pro systémové databáze jiné než msdb. Indexy se zakázanými zámky stránek nemají nárok na automatické komprimace.

Další informace o datových stránkách najdete v průvodci architekturou stránky a rozsahu.

Další informace o indexech najdete v tématu Architektura indexu a průvodce návrhem.

Porovnání s reorganizací indexu a opětovným sestavením indexu

Zvažte následující rozdíly mezi tradičními operacemi údržby indexů (změna uspořádání indexu, opětovné sestavení indexu) a automatickým komprimací indexu:

Úvahy Doporučení
Komprimace probíhá nepřetržitě a s minimální režií, pokud se mění data v databázi. Abyste získali výhody, které by tyto úlohy mohly poskytovat, nemusíte nastavovat, monitorovat a udržovat úlohy údržby indexů.
Na rozdíl od změny uspořádání a opětovného sestavení indexu, které zpracovávají všechny stránky, proces komprimace bere v úvahu pouze stránky upravené po povolení automatického komprimace indexu. Pokud je hustota stránky indexu již nízká, zvažte možnost spustit jednorázovou reorganizaci indexu nebo opětovné sestavení indexu, aby se zvýšila. Tato jednorázová operace je dodatečnou optimalizací, která okamžitě zvýší hustotu stránky. Od tohoto okamžiku automatické komprimace udržuje indexy kompaktní bez zásahu uživatele.
Každá operace opětovného sestavení indexu vyžaduje značné volné místo v datových souborech, které se běžně rovnají velikosti opětovného sestavení indexu nebo oddílu. Nemusíte přidělovat volné místo v datových souborech pro automatické komprimace indexu ani pro přeuspořádání indexů.
Na rozdíl od opětovného sestavení indexu nebo změna uspořádání indexu komprimace nezmenšuje fragmentaci indexu. Vyšší hustota stránky po komprimaci je důležitější než fragmentace indexu. U většiny úloh nemá vyšší fragmentace indexu vliv na výkon dotazů ani spotřebu prostředků.
Pokud je faktor výplně indexu menší než 100 procent, ale množství dat na stránce překročí faktor výplně, ani komprimace indexu ani změna uspořádání nepřesune řádky mimo stránku. Opětovné sestavení indexu vytvoří nové stránky a vyplní je podle faktoru vyplnění. U většiny úloh se upřednostňuje vyšší hustota stránek. Úlohy, které vyžadují nižší faktor vyplnění, aby se snížil počet rozdělení stránek, můžou být užitečné při občasné opětovném sestavení indexu. Opětovné sestavení vytvoří stránky s nižší hustotou stránky, která odpovídá faktoru výplně.
Na rozdíl od opětovného sestavení indexu se komprimace neaktualizuje statistiky indexu. Pokud automatická aktualizace statistik není pro vaši úlohu dostatečná a při aktualizaci statistik spoléháte na opětovné sestavení indexu, zvažte použití automatického komprimace v kombinaci s úlohou aktualizace statistik.

Další informace o reorganizaci a opětovném sestavení indexu naleznete v tématu Optimalizace údržby indexů za účelem zlepšení výkonu dotazů a snížení spotřeby prostředků.

Hustota stránek a fragmentace indexu

Hustota stránky a fragmentace indexu jsou dvě metriky, které odrážejí spotřebu místa indexem a můžou ovlivnit výkon dotazů. Funkce dynamické správy (DMF) sys.dm_db_index_physical_stats hlásí tyto metriky ve sloupcích a avg_page_space_used_in_percent.

Komprimace zvyšuje hustotu stránky tím, že ukládá více řádků na stejnou stránku, což zlepšuje výkon a snižuje spotřebu prostředků.

Při povolení automatického komprimace indexu můžete pozorovat, že fragmentace indexů je vyšší. Pokud k této podmínce dojde, zvažte:

Úvahy Doporučení
V některých úlohách náročných na zápis se stránky můžou brzy po komprimování znovu rozdělit. Rozdělení stránek zvyšuje fragmentaci indexu. Pokud dojde k ovlivnění výkonu úloh, použijte jednorázové opětovné sestavení indexu s mírně nižším faktorem výplně , abyste snížili rozdělení stránek po komprimování.

Například nastavte faktor výplně v rozsahu 70–95 procent. Nezmenšujte ale faktor výplně zbytečně nebo ho nenastavujte příliš nízko. Většina úloh dosahuje optimálního výkonu a využití prostředků s faktorem výplně nastaveným na výchozí 100 procent.
Uvolnění prázdné stránky během komprimace může v rozsahu vytvořit mezeru v posloupnosti číslování stránek. Mezery v rozsazích zvyšují fragmentaci indexů, což může potenciálně snížit efektivitu read-ahead I/O. I u úloh, které využívají čtení dopředu, je výkonový dopad vyšší fragmentace minimalizován, protože dotazy po kompaktaci čtou méně stránek.

Návod

U většiny úloh převáží výhody vyšší hustoty stránek jakýkoli dopad na výkon z vyšší fragmentace indexu.

Monitorování automatického zhutňování indexu

Pokud chcete zjistit efektivitu automatického komprimace indexu, můžete monitorovat metriky klíčových indexů, jako je počet stránek, průměrná hustota stránek a průměrná fragmentace indexu v průběhu času. Další informace najdete v příkladu Určení metrik indexu klíčů .

Kumulativní statistiky komprimace můžete monitorovat pro každý oddíl indexu pomocí funkce dynamické správy sys.dm_db_index_operational_stats . Mezi tyto statistiky patří dokončené a přeskočené pokusy o komprimace, přesunuté řádky a uvolněné stránky. Další informace najdete v příkladu Zobrazení statistik kompaktace pro každý oddíl indexu.

Pomocí rozšířených událostí můžete také monitorovat podrobné statistiky komprimace. Další informace najdete v příkladu použití rozšířené události ke sledování statistik komprimace .

Omezení

Proces automatického komprimace indexu bere v úvahu pouze stránky na úrovni listu indexu B-stromu, které jsou obsaženy v IN_ROW_DATA alokační jednotce. To zahrnuje stránky v:

  • Clusterované indexy a omezení
  • Neclusterované indexy a omezení
  • Indexy B-tree v interních tabulkách, jež ukládají speciální typy indexů, jako jsou XML, fulltextové, prostorové a columnstore indexy ve vnitřních sadách řádků.

Na automatické komprimování indexů nemají nárok následující typy stránek:

  • Stránky v tabulkách haldy
  • Stránky v jednotkách přidělení ROW_OVERFLOW_DATA nebo LOB_DATA.
  • Stránky v komprimovaných skupinách řádků indexů typu columnstore.
  • Stránky v tabulkách optimalizovaných pro paměť

Často kladené otázky (FAQ)

Tato část odpovídá na běžné otázky týkající se automatického komprimace indexů.

Vyžaduje se restartování nebo výhradní přístup k databázi, aby bylo možné povolit nebo zakázat automatické komprimace?

Ne. Komprimace se spustí nebo zastaví během několika minut po spuštění ALTER DATABASE ... SET AUTOMATIC_INDEX_COMPACTION = ... příkazu.

Jak to ovlivňuje výkon dotazů?

Dotazy obvykle běží rychleji a využívají méně vstupně-výstupních operací disku, paměti a procesoru. Toto vylepšení je nejvíce patrné v úlohách s významnou aktivitou zápisu, která by jinak způsobovala nadýmání indexu.

Jak se mění využití úložného prostoru?

Komprimace snižuje růst využitého místa v datových souborech. Na rozdíl od zmenšení databáze ale nezmenšuje přidělenou velikost datových souborů.

Dochází k přetížení?

U většiny úloh nejsou náklady znatelné. U úloh náročných na zápis si můžete všimnout zvýšení vstupně-výstupních operací transakčního protokolu a velikosti záloh transakčních protokolů.

Může to způsobit blokování?

Blokování kvůli automatické komprimaci není pravděpodobné. Pokud dojde k nějakému blokování, je to krátkodobé a přechodné (milisekundy).

Pokud je dotaz zablokovaný, zkontrolujte příkaz hlavního blokátoru v sys.dm_exec_requests. Automatické komprimace mohou blokovat dotazy, pokud je příkaz VERSION_CLEANER_MAIN nebo VERSION_CLEANER_WORKER.

Respektuje to koeficient výplně?

Automatické komprimace nepoužívá volné místo na stránce vyhrazené faktorem výplně. Pokud je však tento vyhrazený prostor již používán předchozími příkazy DML, komprimace ho neumožní.

Funguje to, pokud index používá kompresi řádků nebo stránek?

Ano. Automatické komprimace odebere prázdné místo ze stránek v indexu. Nezáleží na tom, jestli jsou data na stránkách komprimovaná nebo ne.

Jak se liší od čištění duchů?

Čištění duchů odstraňuje ze stránek měkce smazané řádky, což zanechává na stránce prázdné místo. Automatické komprimace odebere prázdné místo na stránkách sloučením dat na méně stránkách.

Co se stane, když spustím opětovné sestavení indexu nebo přeuspořádání indexu, když je povolená automatická komprimace?

Automatická komprimace přeskočí indexy, které se znovu sestavují nebo reorganizují, včetně indexů uprostřed pozastavených operací s indexy s možností obnovení.

Může automatická kompakce zabránit automatickému pozastavení serverless databáze?

Ne. Indexy, které zůstávají způsobilé k automatické kompakci po pozastavení databáze, jsou po obnovení databáze zkompaktovány. Automatická kompence indexů neobnovuje pozastavenou serverless databázi. Více informací naleznete v části Automatické pozastavení a automatické obnovení.

Příklady

Spusťte následující příklady T-SQL v uživatelské databázi, ne v master databázi.

Stanovení klíčových metrik indexu

Následující dotaz vrátí počet stránek na listové úrovni indexu, jeho průměrnou hustotu stránky a fragmentaci ve sloupcích page_count, avg_page_space_used_in_percent a avg_fragmentation_in_percent pro indexy, které mají nárok na automatickou kompakci. Dotaz také vrátí řádek souhrnů obsahující tyto metriky agregované pro všechny indexy v databázi.

SELECT COALESCE (OBJECT_SCHEMA_NAME(ips.object_id), '<Total>') AS schema_name,
       COALESCE (OBJECT_NAME(ips.object_id), '<Total>') AS object_name,
       COALESCE (i.name, '<Total>') AS index_name,
       COALESCE (i.type_desc, '<Total>') AS index_type,
       COALESCE (ips.partition_number, NULL) AS partition_number,
       AVG(ips.avg_page_space_used_in_percent) AS avg_page_space_used_in_percent,
       AVG(ips.avg_fragmentation_in_percent) AS avg_fragmentation_in_percent,
       SUM(ips.record_count) AS record_count,
       SUM(ips.page_count) AS page_count
FROM sys.dm_db_index_physical_stats(DB_ID(), DEFAULT, DEFAULT, DEFAULT, 'SAMPLED') AS ips
     INNER JOIN sys.indexes AS i
         ON ips.object_id = i.object_id
        AND ips.index_id = i.index_id
WHERE i.type_desc IN ('CLUSTERED', 'NONCLUSTERED', 'XML', 'SPATIAL')
      AND ips.index_level = 0
      AND ips.page_count > 0
      AND ips.alloc_unit_type_desc = 'IN_ROW_DATA'
GROUP BY ROLLUP(ips.object_id, i.name, i.type_desc, ips.partition_number)
HAVING ips.object_id IS NULL
       AND ips.object_id IS NULL
       AND i.name IS NULL
       AND i.type_desc IS NULL
       AND ips.partition_number IS NULL
       OR ips.object_id IS NOT NULL
          AND ips.object_id IS NOT NULL
          AND i.name IS NOT NULL
          AND i.type_desc IS NOT NULL
          AND ips.partition_number IS NOT NULL
ORDER BY IIF (ips.object_id IS NULL, 0, 1), page_count DESC;

Dotaz vrátí přibližné výsledky na základě vzorku podmnožiny stránek. Změňte SAMPLED na DETAILED pro přesnější výsledky. Použití DETAILED u velkých databází může trvat mnohem déle, protože všechny oprávněné indexy v databázi jsou plně prohledány. Další informace najdete v tématu sys.dm_db_index_physical_stats.

Zobrazení statistik komprimace pro každý oddíl indexu

Pomocí následujícího dotazu můžete zobrazit automatické statistiky komprimace pro každý oddíl indexu v aktuální databázi:

SELECT OBJECT_SCHEMA_NAME(ios.object_id) AS schema_name,
       OBJECT_NAME(ios.object_id) AS object_name,
       i.name AS index_name,
       i.type_desc AS index_type,
       ios.partition_number AS partition_number,
       ios.compaction_attempt_count,
       ios.compaction_complete_count,
       ios.compaction_skip_count,
       ios.compaction_ineligible_count,
       ios.compaction_failure_count,
       ios.compaction_row_move_count,
       ios.compaction_page_deallocation_count
FROM sys.dm_db_index_operational_stats(DB_ID(), DEFAULT, DEFAULT, DEFAULT) AS ios
     INNER JOIN sys.indexes AS i
         ON ios.object_id = i.object_id
        AND ios.index_id = i.index_id
WHERE i.type_desc IN ('CLUSTERED', 'NONCLUSTERED', 'XML', 'SPATIAL')
      AND OBJECT_SCHEMA_NAME(ios.object_id) <> 'sys';

Další informace najdete v tématu sys.dm_db_index_operational_stats.

Použití rozšířené události ke sledování statistik komprimace

Rozšířenou auto_index_compaction_stats událost můžete použít k monitorování statistik komprimace pro databázi. Událost se aktivuje každých 10 minut. Obsahuje data, jako je počet řádků přesunutých mezi stránkami pro kompakci indexu, počet uvolněných stránek a počet pokusů o kompakci, které byly z různých důvodů vynechány. Statistiky hlášené každou událostí jsou kumulativní od spuštění databázového stroje.

Následující příklad T-SQL vytvoří a spustí sezení událostí, které shromažďuje data události auto_index_compaction_stats do cíle typu ring_buffer. Dotaz porovná aktuální a předchozí událost a vrátí statistiku komprimace pro každý 10minutový interval. Vzhledem k tomu, že dotaz vyžaduje alespoň dvě události k výpočtu statistiky pro časový interval, nemusí po spuštění relace událostí vrátit žádná data po dobu až 20 minut.

/*
Create and start an event session collecting the auto_index_compaction_stats event
into a ring_buffer target
*/
IF NOT EXISTS (SELECT 1
               FROM sys.dm_xe_database_sessions
               WHERE name = N'automatic_index_compaction')
  BEGIN
      CREATE EVENT SESSION automatic_index_compaction ON DATABASE
      ADD EVENT sqlserver.auto_index_compaction_stats
      ADD TARGET package0.ring_buffer (SET MAX_MEMORY = 1024);

      ALTER EVENT SESSION automatic_index_compaction ON DATABASE STATE = START;
  END

/* Get event data from the ring_buffer target */
DECLARE @EventData AS XML = (SELECT CAST (xst.target_data AS XML) AS TargetData
                             FROM sys.dm_xe_database_session_targets AS xst
                                  INNER JOIN sys.dm_xe_database_sessions AS xs
                                      ON xst.event_session_address = xs.address
                             WHERE xs.name = N'automatic_index_compaction');

/* Return statistics for each 10-minute interval */
WITH compaction_stats_event AS (
    SELECT d.value('@timestamp', 'datetimeoffset') AS timestamp,
           d.value('(data[@name = "database_id"]/value/text())[1]', 'smallint') AS database_id,
           d.value('(data[@name = "compact_attempts"]/value/text())[1]', 'bigint') AS compact_attempts,
           d.value('(data[@name = "compact_completed"]/value/text())[1]', 'bigint') AS compact_completed,
           d.value('(data[@name = "pages_deallocated_compaction"]/value/text())[1]', 'bigint') AS pages_deallocated_compaction,
           d.value('(data[@name = "rows_moved"]/value/text())[1]', 'bigint') AS rows_moved
    FROM @EventData.nodes('/RingBufferTarget/event') AS e(d)
    WHERE e.d.value('@name', 'sysname') = 'auto_index_compaction_stats'
),
timestamp_map AS (
    SELECT database_id,
           timestamp,
           LAG(timestamp) OVER (PARTITION BY database_id ORDER BY timestamp) AS previous_timestamp
    FROM compaction_stats_event
)
SELECT c.timestamp,
       c.database_id,
       c.compact_attempts - p.compact_attempts AS compact_attempts,
       c.compact_completed - p.compact_completed AS compact_completed,
       c.pages_deallocated_compaction - p.pages_deallocated_compaction AS pages_deallocated_compaction,
       c.rows_moved - p.rows_moved AS rows_moved
FROM compaction_stats_event AS c
     INNER JOIN timestamp_map AS tm
         ON c.timestamp = tm.timestamp
        AND c.database_id = tm.database_id
     INNER JOIN compaction_stats_event AS p
         ON tm.previous_timestamp = p.timestamp
        AND tm.database_id = p.database_id
ORDER BY timestamp DESC;

Předchozí dotaz můžete upravit tak, aby zahrnoval další pole událostí a vrátil další statistiky, například počet pokusů o komprimace vynechaných z různých důvodů. Pomocí následujícího dotazu zobrazíte všechna pole auto_index_compaction_stats události a jejich popisy.

SELECT name,
       type_name,
       description
FROM sys.dm_xe_object_columns
WHERE object_name = N'auto_index_compaction_stats'
      AND column_type = N'data';

Odeslat názory

Microsoft je dychtivá slyšet vaši zpětnou vazbu týkající se automatického komprimace indexů. Pošlete zpětnou vazbu k produktu publikováním nového nápadu na fóru pro zpětnou vazbu SQL. Ostatní členové komunity mohou udělovat hlasy vašim nápadům a návrhům a komentovat je. Komunitní hlasování a komentáře pomáhají Microsoft plánování a stanovení priorit vylepšení produktů.