sys.dm_db_index_physical_stats (Transact-SQL)
gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance
Returnerar storleks- och fragmenteringsinformation för data och index för den angivna tabellen eller vyn i SQL Server Database Engine. För ett index returneras en rad för varje nivå i B-trädet i varje partition. För en heap returneras en rad för IN_ROW_DATA
allokeringsenhet för varje partition. För stora objektdata returneras en rad för LOB_DATA
allokeringsenhet för varje partition. Om rad-overflow-data finns i tabellen returneras en rad för ROW_OVERFLOW_DATA
allokeringsenhet i varje partition.
Not
I dokumentationen används termen B-träd vanligtvis som referens till index. I radlagringsindex implementerar databasmotorn ett B+-träd. Detta gäller inte för kolumnlagringsindex eller index i minnesoptimerade tabeller. Mer information finns i arkitekturen och designguiden för SQL Server och Azure SQL-index.
sys.dm_db_index_physical_stats
returnerar inte information om minnesoptimerade index. Information om minnesoptimerad indexanvändning finns i sys.dm_db_xtp_index_stats.
Om du frågar sys.dm_db_index_physical_stats
på en serverinstans som är värd för en tillgänglighetsgrupp läsbar sekundär replikkan det uppstå ett REDO
blockeringsproblem. Detta beror på att den här dynamiska hanteringsvyn hämtar ett Intent-Shared(IS) lås på den angivna användartabellen eller vyn som kan blockera begäranden av en REDO
tråd för ett exklusivt (X) lås på användartabellen eller vyn.
Transact-SQL syntaxkonventioner
Syntax
sys.dm_db_index_physical_stats (
{ database_id | NULL | 0 | DEFAULT }
, { object_id | NULL | 0 | DEFAULT }
, { index_id | NULL | 0 | -1 | DEFAULT }
, { partition_number | NULL | 0 | DEFAULT }
, { mode | NULL | DEFAULT }
)
Argument
database_id | NULL | 0 | STANDARD
Databasens ID.
database_id är smallint. Giltiga indata är ID för en databas, NULL
, 0
eller DEFAULT
. Standardvärdet är 0
.
NULL
, 0
och DEFAULT
är motsvarande värden i den här kontexten.
Ange NULL
för att returnera information för alla databaser i SQL Server-instansen. Om du anger NULL
för database_idmåste du också ange NULL
för object_id, index_idoch partition_number.
Den inbyggda funktionen DB_ID kan anges. När du använder DB_ID
utan att ange ett databasnamn måste kompatibilitetsnivån för den aktuella databasen vara 90
eller större.
object_id | NULL | 0 | STANDARD
Objekt-ID för tabellen eller visa indexet är aktiverat. object_id är int. Giltiga indata är ID för en tabell och vy, NULL
, 0
eller DEFAULT
. Standardvärdet är 0
.
NULL
, 0
och DEFAULT
är motsvarande värden i den här kontexten.
I SQL Server 2016 (13.x) och senare versioner innehåller giltiga indata även könamnet för service broker eller köns interna tabellnamn. När standardparametrar tillämpas (dvs. alla objekt, alla index osv.), ingår fragmenteringsinformation för alla köer i resultatuppsättningen.
Ange NULL
för att returnera information för alla tabeller och vyer i den angivna databasen. Om du anger NULL
för object_idmåste du också ange NULL
för index_id och partition_number.
index_id | 0 | NULL | -1 | STANDARD
Indexets ID.
index_id är int. Giltiga indata är ID för ett index, 0
om object_id är en heap, NULL
, -1
eller DEFAULT
. Standardvärdet är -1
.
NULL
, -1
och DEFAULT
är motsvarande värden i den här kontexten.
Ange NULL
för att returnera information för alla index för en bastabell eller vy. Om du anger NULL
för index_idmåste du också ange NULL
för partition_number.
partition_number | NULL | 0 | STANDARD
Partitionsnumret i objektet.
partition_number är int. Giltiga indata är partition_number för ett index eller en heap, NULL
, 0
eller DEFAULT
. Standardvärdet är 0
.
NULL
, 0
och DEFAULT
är motsvarande värden i den här kontexten.
Ange NULL
för att returnera information för alla partitioner i det ägande objektet.
partition_number är 1-baserad. Ett icke-partitionerat index eller en heap har partition_number inställt på 1
.
läge | NULL | STANDARD
Namnet på läget.
läge anger genomsökningsnivån som används för att hämta statistik.
läge är sysname. Giltiga indata är DEFAULT
, NULL
, LIMITED
, SAMPLED
eller DETAILED
. Standardvärdet (NULL
) är LIMITED
.
Tabellen returnerades
Kolumnnamn | Datatyp | Beskrivning |
---|---|---|
database_id |
liten | Databas-ID för tabellen eller vyn. I Azure SQL Database är värdena unika i en enskild databas eller en elastisk pool, men inte inom en logisk server. |
object_id |
int | Objekt-ID för tabellen eller vyn som indexet är på. |
index_id |
int | Index-ID för ett index.0 = Heap. |
partition_number |
int | 1-baserat partitionsnummer i det ägande objektet. en tabell, vy eller ett index.1 = Icke-partitionerat index eller heap. |
index_type_desc |
nvarchar(60) | Beskrivning av indextypen: - HEAP - CLUSTERED INDEX - NONCLUSTERED INDEX - PRIMARY XML INDEX - EXTENDED INDEX - XML INDEX - COLUMNSTORE MAPPING INDEX (intern)- COLUMNSTORE DELETEBUFFER INDEX (intern)- COLUMNSTORE DELETEBITMAP INDEX (intern) |
alloc_unit_type_desc |
nvarchar(60) | Beskrivning av typ av allokeringsenhet: - IN_ROW_DATA - LOB_DATA - ROW_OVERFLOW_DATA Den LOB_DATA allokeringsenheten innehåller data som lagras i kolumner av typen text, ntext, bild, varchar(max), nvarchar(max), varbinary(max)och xml-. Mer information finns i Datatyper.Den ROW_OVERFLOW_DATA allokeringsenheten innehåller data som lagras i kolumner av typen varchar(n), nvarchar(n), varbinary(n)och sql_variant som skickas utanför rad. |
index_depth |
pytteliten | Antal indexnivåer.1 = Heap, LOB_DATA eller ROW_OVERFLOW_DATA allokeringsenhet. |
index_level |
pytteliten | Aktuell nivå för indexet.0 för index lövnivåer, heaps och LOB_DATA eller ROW_OVERFLOW_DATA allokeringsenheter.Större än 0 för icke-lågnivåindex.
index_level är högst på rotnivån för ett index.Icke-nivånivå för index bearbetas endast när läge är DETAILED . |
avg_fragmentation_in_percent |
flyttal | Logisk fragmentering för index eller omfattningsfragmentering för heaps i IN_ROW_DATA allokeringsenhet.Värdet mäts som en procentandel och tar hänsyn till flera filer. Definitioner av logisk fragmentering och omfattningsfragmentering finns i Kommentarer. 0 för LOB_DATA och ROW_OVERFLOW_DATA allokeringsenheter.
NULL för heaps när läge är SAMPLED . |
fragment_count |
bigint | Antal fragment i lövnivån för en IN_ROW_DATA allokeringsenhet. Mer information om fragment finns i Kommentarer.NULL för icke-nivånivåer för ett index och LOB_DATA eller ROW_OVERFLOW_DATA allokeringsenheter.
NULL för heaps när läge är SAMPLED . |
avg_fragment_size_in_pages |
flyttal | Genomsnittligt antal sidor i ett fragment i lövnivån för en IN_ROW_DATA allokeringsenhet.NULL för icke-nivånivåer för ett index och LOB_DATA eller ROW_OVERFLOW_DATA allokeringsenheter.
NULL för heaps när läge är SAMPLED . |
page_count |
bigint | Totalt antal index- eller datasidor. För ett index är det totala antalet indexsidor på den aktuella nivån i B-trädet i IN_ROW_DATA allokeringsenhet.För en heap är det totala antalet datasidor i IN_ROW_DATA allokeringsenhet.För LOB_DATA eller ROW_OVERFLOW_DATA allokeringsenheter, totalt antal sidor i allokeringsenheten. |
avg_page_space_used_in_percent |
flyttal | Genomsnittlig procentandel av tillgängligt lagringsutrymme för data som används på alla sidor. För ett index gäller medelvärdet för den aktuella nivån för B-trädet i IN_ROW_DATA allokeringsenhet.För en heap är medelvärdet av alla datasidor i IN_ROW_DATA allokeringsenhet.För LOB_DATA eller ROW_OVERFLOW_DATA allokeringsenheter, medelvärdet av alla sidor i allokeringsenheten.
NULL när läge är LIMITED . |
record_count |
bigint | Totalt antal poster. För ett index gäller det totala antalet poster för den aktuella nivån för B-trädet i IN_ROW_DATA allokeringsenhet.För en heap är det totala antalet poster i IN_ROW_DATA allokeringsenhet.Obs! För en heap kanske antalet poster som returneras från den här funktionen inte matchar antalet rader som returneras genom att köra en SELECT COUNT(*) mot heapen. Det beror på att en rad kan innehålla flera poster. I vissa uppdateringssituationer kan till exempel en enskild heap-rad ha en vidarebefordrande post och en vidarebefordrad post som ett resultat av uppdateringsåtgärden. Dessutom delas de flesta stora LOB-rader upp i flera poster i LOB_DATA lagring.För LOB_DATA eller ROW_OVERFLOW_DATA allokeringsenheter, det totala antalet poster i den fullständiga allokeringsenheten.
NULL när läge är LIMITED . |
ghost_record_count |
bigint | Antal spökposter som är redo för borttagning av spökrensningsaktiviteten i allokeringsenheten.0 för icke-nivånivåer för ett index i IN_ROW_DATA allokeringsenhet.
NULL när läge är LIMITED . |
version_ghost_record_count |
bigint | Antal spökposter som behålls av en utestående ögonblicksbildisoleringstransaktion i en allokeringsenhet.0 för icke-nivånivåer för ett index i IN_ROW_DATA allokeringsenhet.
NULL när läge är LIMITED . |
min_record_size_in_bytes |
int | Minsta poststorlek i byte. För ett index gäller den minsta poststorleken för den aktuella nivån för B-trädet i IN_ROW_DATA allokeringsenhet.För en heap är den minsta poststorleken i IN_ROW_DATA allokeringsenhet.För LOB_DATA eller ROW_OVERFLOW_DATA allokeringsenheter, den minsta poststorleken i den fullständiga allokeringsenheten.
NULL när läge är LIMITED . |
max_record_size_in_bytes |
int | Maximal poststorlek i byte. För ett index gäller den maximala poststorleken för den aktuella nivån för B-trädet i IN_ROW_DATA allokeringsenhet.För en heap är den maximala poststorleken i IN_ROW_DATA allokeringsenhet.För LOB_DATA eller ROW_OVERFLOW_DATA allokeringsenheter, den maximala poststorleken i den fullständiga allokeringsenheten.
NULL när läge är LIMITED . |
avg_record_size_in_bytes |
flyttal | Genomsnittlig poststorlek i byte. För ett index gäller den genomsnittliga poststorleken för den aktuella nivån för B-trädet i IN_ROW_DATA allokeringsenhet.För en heap är den genomsnittliga poststorleken i IN_ROW_DATA allokeringsenhet.För LOB_DATA eller ROW_OVERFLOW_DATA allokeringsenheter, den genomsnittliga poststorleken i den fullständiga allokeringsenheten.
NULL när läge är LIMITED . |
forwarded_record_count |
bigint | Antal poster i en heap som har framåtriktade pekare till en annan dataplats. (Det här tillståndet inträffar under en uppdatering, när det inte finns tillräckligt med utrymme för att lagra den nya raden på den ursprungliga platsen.)NULL för allokeringsenheter som inte är IN_ROW_DATA allokeringsenheter för en heap.
NULL för heaps när läge är LIMITED . |
compressed_page_count |
bigint | Antalet komprimerade sidor. För heaps komprimeras inte nyligen allokerade sidor PAGE . En heap komprimeras PAGE under två särskilda villkor: när data massimporteras eller när en heap återskapas. Vanliga DML-åtgärder som orsakar sidallokeringar komprimeras inte PAGE . Återskapa en heap när värdet för compressed_page_count växer större än det tröskelvärde du vill ha.För tabeller som har ett grupperat index anger compressed_page_count -värdet effektiviteten för PAGE komprimering. |
hobt_id |
bigint | Heap- eller B-träd-ID för indexet eller partitionen. För kolumnlagringsindex är detta ID för en raduppsättning som spårar interna kolumnlagringsdata för en partition. Raduppsättningarna lagras som datahögar eller B-träd. De har samma index-ID som det överordnade kolumnlagringsindexet. Mer information finns i sys.internal_partitions. |
columnstore_delete_buffer_state |
pytteliten | 0 = NOT_APPLICABLE 1 = OPEN 2 = DRAINING 3 = FLUSHING 4 = RETIRING 5 = READY gäller för: SQL Server 2016 (13.x) och senare versioner, Azure SQL Database och Azure SQL Managed Instance |
columnstore_delete_buffer_state_desc |
nvarchar(60) |
NOT VALID – det överordnade indexet är inte ett kolumnlagringsindex.OPEN – deleters och skannrar använder detta.DRAINING – borttagarna töms, men skannrar använder det fortfarande.FLUSHING – bufferten stängs och rader i bufferten skrivs till bitmappen delete.RETIRING – rader i den stängda borttagningsbufferten skrevs till bitmappen för borttagning, men bufferten har inte trunkerats eftersom skannrar fortfarande använder den. Nya skannrar behöver inte använda den tillbakadragna bufferten eftersom den öppna bufferten räcker.READY – Den här borttagningsbufferten är klar att användas.gäller för: SQL Server 2016 (13.x) och senare versioner, Azure SQL Database och Azure SQL Managed Instance |
version_record_count |
bigint | Det här är antalet radversionsposter som underhålls i det här indexet. Dessa radversioner underhålls av funktionen Accelererad databasåterställning. gäller för: SQL Server 2019 (15.x) och senare versioner och Azure SQL Database |
inrow_version_record_count |
bigint | Antal adr-versionsposter som sparas på dataraden för snabb hämtning. gäller för: SQL Server 2019 (15.x) och senare versioner och Azure SQL Database |
inrow_diff_version_record_count |
bigint | Antal adr-versionsposter som sparas i form av skillnader från basversionen. gäller för: SQL Server 2019 (15.x) och senare versioner och Azure SQL Database |
total_inrow_version_payload_size_in_bytes |
bigint | Total storlek i byte för poster i radversion för det här indexet. gäller för: SQL Server 2019 (15.x) och senare versioner och Azure SQL Database |
offrow_regular_version_record_count |
bigint | Antal versionsposter som sparas utanför den ursprungliga dataraden. gäller för: SQL Server 2019 (15.x) och senare versioner och Azure SQL Database |
offrow_long_term_version_record_count |
bigint | Antal versionsposter som anses vara långsiktiga. gäller för: SQL Server 2019 (15.x) och senare versioner och Azure SQL Database |
Not
I dokumentationen används termen B-träd vanligtvis som referens till index. I radlagringsindex implementerar databasmotorn ett B+-träd. Detta gäller inte för kolumnlagringsindex eller index i minnesoptimerade tabeller. Mer information finns i arkitekturen och designguiden för SQL Server och Azure SQL-index.
Anmärkningar
Funktionen sys.dm_db_index_physical_stats
dynamisk hantering ersätter DBCC SHOWCONTIG
-instruktionen.
Genomsökningslägen
Läget där funktionen körs avgör vilken genomsökningsnivå som utförs för att hämta de statistiska data som används av funktionen.
läge anges som LIMITED
, SAMPLED
eller DETAILED
. Funktionen passerar sidkedjorna för de allokeringsenheter som utgör de angivna partitionerna i tabellen eller indexet.
sys.dm_db_index_physical_stats
kräver endast ett Intent-Shared(IS) tabelllås, oavsett vilket läge det körs i.
Det LIMITED
läget är det snabbaste läget och söker igenom det minsta antalet sidor. För ett index genomsöks endast sidorna på överordnad nivå i B-trädet (dvs. sidorna ovanför lövnivån). För en heap granskas de associerade PFS- och IAM-sidorna och datasidorna i en heap genomsöks i LIMITED
läge.
Med LIMITED
läge är compressed_page_count
NULL
eftersom databasmotorn endast söker igenom icke-bladsidor i B-trädet och IAM- och PFS-sidorna i heapen. Använd SAMPLED
läge för att hämta ett uppskattat värde för compressed_page_count
och använd DETAILED
läge för att hämta det faktiska värdet för compressed_page_count
.
SAMPLED
-läget returnerar statistik baserat på ett urval på 1 procent av alla sidor i indexet eller heapen. Resultat i SAMPLED
läge ska betraktas som ungefärligt. Om indexet eller heapen har färre än 10 000 sidor används DETAILED
läge i stället för SAMPLED
.
Läget DETAILED
söker igenom alla sidor och returnerar all statistik.
Lägena är progressivt långsammare från LIMITED
till DETAILED
eftersom mer arbete utförs i varje läge. Om du snabbt vill mäta storleken eller fragmenteringsnivån för en tabell eller ett index använder du läget LIMITED
. Det är snabbast och returnerar inte en rad för varje icke-nivå i IN_ROW_DATA
allokeringsenhet för indexet.
Använda systemfunktioner för att ange parametervärden
Du kan använda Transact-SQL-funktionerna DB_ID och OBJECT_ID för att ange ett värde för parametrarna database_id och object_id. Att skicka värden som inte är giltiga för dessa funktioner kan dock orsaka oavsiktliga resultat. Om databasen eller objektnamnet till exempel inte kan hittas eftersom de inte finns eller stavas felaktigt returnerar båda funktionerna NULL
. Funktionen sys.dm_db_index_physical_stats
tolkar NULL
som ett jokerteckenvärde som anger alla databaser eller alla objekt.
Dessutom bearbetas funktionen OBJECT_ID
innan funktionen sys.dm_db_index_physical_stats
anropas och utvärderas därför i kontexten för den aktuella databasen, inte den databas som anges i database_id. Det här beteendet kan göra att funktionen OBJECT_ID
returnerar ett NULL
värde. eller, om objektnamnet finns i både den aktuella databaskontexten och den angivna databasen, returneras ett felmeddelande. Följande exempel visar dessa oavsiktliga resultat.
USE master;
GO
-- In this example, OBJECT_ID is evaluated in the context of the master database.
-- Because Person.Address does not exist in master, the function returns NULL.
-- When NULL is specified as an object_id, all objects in the database are returned.
-- The same results are returned when an object that is not valid is specified.
SELECT * FROM sys.dm_db_index_physical_stats
(DB_ID(N'AdventureWorks2022'), OBJECT_ID(N'Person.Address'), NULL, NULL , 'DETAILED');
GO
-- This example demonstrates the results of specifying a valid object name
-- that exists in both the current database context and
-- in the database specified in the database_id parameter of the
-- sys.dm_db_index_physical_stats function.
-- An error is returned because the ID value returned by OBJECT_ID does not
-- match the ID value of the object in the specified database.
CREATE DATABASE Test;
GO
USE Test;
GO
CREATE SCHEMA Person;
GO
CREATE Table Person.Address(c1 int);
GO
USE AdventureWorks2022;
GO
SELECT * FROM sys.dm_db_index_physical_stats
(DB_ID(N'Test'), OBJECT_ID(N'Person.Address'), NULL, NULL , 'DETAILED');
GO
-- Clean up temporary database.
DROP DATABASE Test;
GO
Bästa praxis
Kontrollera alltid att ett giltigt ID returneras när du använder DB_ID
eller OBJECT_ID
. När du till exempel använder OBJECT_ID
anger du ett namn i tre delar, till exempel OBJECT_ID(N'AdventureWorks2022.Person.Address')
eller testar värdet som returneras av funktionerna innan du använder dem i funktionen sys.dm_db_index_physical_stats
. Exempel A och B som följer visar ett säkert sätt att ange databas- och objekt-ID:n.
Identifiera fragmentering
Fragmentering sker genom processen med dataändringar (INSERT
, UPDATE
och DELETE
-instruktioner) som görs mot tabellen och därför till de index som definierats i tabellen. Eftersom dessa ändringar vanligtvis inte fördelas lika mellan raderna i tabellen och indexen kan varje sidas fullhet variera över tid. För frågor som genomsöker en del av eller alla index i en tabell kan den här typen av fragmentering orsaka fler sidläsningar, vilket hindrar parallell genomsökning av data.
Fragmenteringsnivån för ett index eller en heap visas i kolumnen avg_fragmentation_in_percent
. För heaps representerar värdet omfattningens fragmentering av heapen. För index representerar värdet den logiska fragmenteringen av indexet. Till skillnad från DBCC SHOWCONTIG
anser algoritmerna för fragmenteringsberäkning i båda fallen lagring som sträcker sig över flera filer och därför är korrekta.
Logisk fragmentering
Det här är procentandelen oordnade sidor i lövsidorna i ett index. En out-of-order-sida är en sida där nästa fysiska sida som allokeras till indexet inte är den sida som pekas på av nästa sida pekare på den aktuella lövsidan.
Fragmentering av omfattning
Det här är procentandelen out-of-order-omfattningar i lövsidorna i en heap. En out-of-order-omfattning är en för vilken omfattningen som innehåller den aktuella sidan för en heap inte fysiskt är nästa utsträckning efter den omfattning som innehåller föregående sida.
Värdet för avg_fragmentation_in_percent
ska vara så nära noll som möjligt för maximal prestanda. Värden från 0 procent till 10 procent kan dock accepteras. Alla metoder för att minska fragmentering, till exempel återskapa, omorganisera eller återskapa, kan användas för att minska dessa värden. Mer information om hur du analyserar fragmenteringsgraden i ett index finns i Optimera indexunderhåll för att förbättra frågeprestanda och minska resursförbrukningen.
Minska fragmentering i ett index
När ett index är fragmenterat på ett sätt som påverkar frågeprestanda finns det tre alternativ för att minska fragmenteringen:
Släpp och återskapa det klustrade indexet.
Om du återskapar ett grupperat index omdistribueras data och resulterar i fullständiga datasidor. Fullhetsnivån kan konfigureras med hjälp av alternativet
FILLFACTOR
iCREATE INDEX
. Nackdelarna med den här metoden är att indexet är offline under släpp- och återskapa-cykeln och att åtgärden är atomisk. Om indexskapandet avbryts återskapas inte indexet. Mer information finns i CREATE INDEX.Använd
ALTER INDEX REORGANIZE
, ersättningen förDBCC INDEXDEFRAG
, för att ordna om bladnivåsidorna i indexet i logisk ordning. Eftersom det här är en onlineåtgärd är indexet tillgängligt medan -instruktionen körs. Åtgärden kan också avbrytas utan att arbetet redan har förlorats. Nackdelen med den här metoden är att den inte gör ett lika bra jobb med att omorganisera data som en indexåterställningsåtgärd, och den uppdaterar inte statistik.Använd
ALTER INDEX REBUILD
, ersättningen förDBCC DBREINDEX
, för att återskapa indexet online eller offline. Mer information finns i ALTER INDEX (Transact-SQL).
Enbart fragmentering är inte en tillräcklig anledning att omorganisera eller återskapa ett index. Den huvudsakliga effekten av fragmentering är att det saktar ned sidläsningsgenomflödet under indexgenomsökningar. Detta orsakar långsammare svarstider. Om frågearbetsbelastningen i en fragmenterad tabell eller ett index inte omfattar genomsökningar, eftersom arbetsbelastningen främst är singleton-sökningar, kan det inte ha någon effekt att ta bort fragmentering.
Not
Att köra DBCC SHRINKFILE
eller DBCC SHRINKDATABASE
kan leda till fragmentering om ett index delvis eller helt flyttas under krympningsåtgärden. Om en krympningsåtgärd måste utföras bör du därför göra det innan fragmenteringen tas bort.
Minska fragmentering i en heap
Om du vill minska fragmenteringen av en heap skapar du ett klustrat index i tabellen och släpper sedan indexet. Detta omdistribuerar data medan det klustrade indexet skapas. Detta gör det också så optimalt som möjligt med tanke på fördelningen av ledigt utrymme som är tillgängligt i databasen. När det klustrade indexet sedan tas bort för att återskapa heapen flyttas inte data och förblir optimalt på plats. Information om hur du utför dessa åtgärder finns i CREATE INDEX and DROP INDEX.
Försiktighet
När du skapar och släpper ett grupperat index i en tabell återskapas alla icke-grupperade index i tabellen två gånger.
Komprimera stora objektdata
Som standard komprimerar ALTER INDEX REORGANIZE
-instruktionen sidor som innehåller stora objektdata (LOB). Eftersom LOB-sidor inte frigörs när de är tomma kan komprimering av dessa data förbättra diskutrymmet om mycket LOB-data tas bort eller om en LOB-kolumn tas bort.
Om du omorganiserar ett angivet grupperat index komprimeras alla LOB-kolumner som finns i det klustrade indexet. Om du omorganiserar ett icke-grupperat index komprimeras alla LOB-kolumner som inte är nyckelkolumner (ingår) i indexet. När ALL
anges i -instruktionen omorganiseras alla index som är associerade med den angivna tabellen eller vyn. Dessutom komprimeras alla LOB-kolumner som är associerade med klustrat index, underliggande tabell eller icke-grupperat index med inkluderade kolumner.
Utvärdera diskutrymmesanvändning
Kolumnen avg_page_space_used_in_percent
anger sidfullhet. För att uppnå optimal diskutrymmesanvändning bör det här värdet vara nära 100 procent för ett index som inte har många slumpmässiga infogningar. Ett index som har många slumpmässiga infogningar och har mycket fullständiga sidor har dock ett ökat antal siddelningar. Detta orsakar mer fragmentering. För att minska siddelningar bör därför värdet vara mindre än 100 procent. Om du återskapar ett index med det FILLFACTOR
angivna alternativet kan sidfullheten ändras så att den passar frågemönstret i indexet. Mer information om fyllningsfaktor finns i Ange fyllningsfaktor för ett index. Dessutom komprimerar ALTER INDEX REORGANIZE
ett index genom att försöka fylla sidor till den FILLFACTOR
som senast angavs. Detta ökar värdet i avg_space_used_in_percent.
ALTER INDEX REORGANIZE
kan inte minska sidfullheten. I stället måste en indexrekonstruktion utföras.
Utvärdera indexfragment
Ett fragment består av fysiskt efterföljande lövsidor i samma fil för en allokeringsenhet. Ett index har minst ett fragment. De maximala fragment som ett index kan ha är lika med antalet sidor i indexets lövnivå. Större fragment innebär att mindre disk-I/O krävs för att läsa samma antal sidor. Ju större avg_fragment_size_in_pages
värde desto bättre prestanda för intervallgenomsökning. Värdena avg_fragment_size_in_pages
och avg_fragmentation_in_percent
är omvänt proportionella mot varandra. Därför bör återskapande eller omorganisering av ett index minska mängden fragmentering och öka fragmentstorleken.
Begränsningar
Returnerar inte data för grupperade kolumnlagringsindex.
Behörigheter
Kräver följande behörigheter:
CONTROL
behörighet för det angivna objektet i databasen.VIEW DATABASE STATE
ellerVIEW DATABASE PERFORMANCE STATE
(SQL Server 2022) behörighet att returnera information om alla objekt i den angivna databasen med hjälp av objektets jokertecken @object_id =NULL
.VIEW SERVER STATE
ellerVIEW SERVER PERFORMANCE STATE
(SQL Server 2022) behörighet att returnera information om alla databaser med hjälp av databasens jokertecken @database_id =NULL
.
Om du beviljar VIEW DATABASE STATE
kan alla objekt i databasen returneras, oavsett vilka CONTROL
behörigheter som nekas för specifika objekt.
Om du nekar VIEW DATABASE STATE
tillåts inte att alla objekt i databasen returneras, oavsett vilka CONTROL
behörigheter som beviljas för specifika objekt. När databasens jokertecken @database_id = NULL
anges utelämnas databasen.
Mer information finns i Dynamiska hanteringsvyer för system.
Exempel
I Transact-SQL kodexempel i den här artikeln används AdventureWorks2022
- eller AdventureWorksDW2022
-exempeldatabasen, som du kan ladda ned från Microsoft SQL Server-exempel och Community Projects startsida.
A. Returnera information om en angiven tabell
I följande exempel returneras storleks- och fragmenteringsstatistik för alla index och partitioner i tabellen Person.Address
. Genomsökningsläget är inställt på LIMITED
för bästa prestanda och för att begränsa den statistik som returneras. För att köra den här frågan krävs minst CONTROL
behörighet i tabellen Person.Address
.
DECLARE @db_id SMALLINT;
DECLARE @object_id INT;
SET @db_id = DB_ID(N'AdventureWorks2022');
SET @object_id = OBJECT_ID(N'AdventureWorks2022.Person.Address');
IF @db_id IS NULL
BEGIN;
PRINT N'Invalid database';
END;
ELSE IF @object_id IS NULL
BEGIN;
PRINT N'Invalid object';
END;
ELSE
BEGIN;
SELECT * FROM sys.dm_db_index_physical_stats(@db_id, @object_id, NULL, NULL , 'LIMITED');
END;
GO
B. Returnera information om en heap
I följande exempel returneras all statistik för heap-dbo.DatabaseLog
i AdventureWorks2022
-databasen. Eftersom tabellen innehåller LOB-data returneras en rad för LOB_DATA
allokeringsenhet utöver raden som returneras för IN_ROW_ALLOCATION_UNIT
som lagrar datasidorna i heapen. För att köra den här frågan krävs minst CONTROL
behörighet i tabellen dbo.DatabaseLog
.
DECLARE @db_id SMALLINT;
DECLARE @object_id INT;
SET @db_id = DB_ID(N'AdventureWorks2022');
SET @object_id = OBJECT_ID(N'AdventureWorks2022.dbo.DatabaseLog');
IF @object_id IS NULL
BEGIN;
PRINT N'Invalid object';
END;
ELSE
BEGIN;
SELECT * FROM sys.dm_db_index_physical_stats(@db_id, @object_id, 0, NULL , 'DETAILED');
END;
GO
C. Returnera information för alla databaser
I följande exempel returneras all statistik för alla tabeller och index i SQL Server-instansen genom att ange jokertecknet NULL
för alla parametrar. För att köra den här frågan krävs behörigheten VIEW SERVER STATE
.
SELECT * FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL);
GO
D. Använd sys.dm_db_index_physical_stats i ett skript för att återskapa eller omorganisera index
I följande exempel omorganiseras eller återskapas automatiskt alla partitioner i en databas som har en genomsnittlig fragmentering över 10 procent. För att köra den här frågan krävs behörigheten VIEW DATABASE STATE
. Det här exemplet anger DB_ID
som den första parametern utan att ange ett databasnamn.
-- Ensure a USE <databasename> statement has been executed first.
SET NOCOUNT ON;
DECLARE @objectid INT;
DECLARE @indexid INT;
DECLARE @partitioncount BIGINT;
DECLARE @schemaname NVARCHAR(130);
DECLARE @objectname NVARCHAR(130);
DECLARE @indexname NVARCHAR(130);
DECLARE @partitionnum BIGINT;
DECLARE @partitions BIGINT;
DECLARE @frag FLOAT;
DECLARE @command NVARCHAR(4000);
-- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function
-- and convert object and index IDs to names.
SELECT object_id AS objectid,
index_id AS indexid,
partition_number AS partitionnum,
avg_fragmentation_in_percent AS frag
INTO #work_to_do
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED')
WHERE avg_fragmentation_in_percent > 10.0
AND index_id > 0;
-- Declare the cursor for the list of partitions to be processed.
DECLARE partitions CURSOR
FOR
SELECT *
FROM #work_to_do;
-- Open the cursor.
OPEN partitions;
-- Loop through the partitions.
WHILE (1 = 1)
BEGIN;
FETCH NEXT
FROM partitions
INTO @objectid,
@indexid,
@partitionnum,
@frag;
IF @@FETCH_STATUS < 0
BREAK;
SELECT @objectname = QUOTENAME(o.name),
@schemaname = QUOTENAME(s.name)
FROM sys.objects AS o
INNER JOIN sys.schemas AS s
ON s.schema_id = o.schema_id
WHERE o.object_id = @objectid;
SELECT @indexname = QUOTENAME(name)
FROM sys.indexes
WHERE object_id = @objectid
AND index_id = @indexid;
SELECT @partitioncount = count(*)
FROM sys.partitions
WHERE object_id = @objectid
AND index_id = @indexid;
-- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding.
IF @frag < 30.0
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
IF @frag >= 30.0
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
IF @partitioncount > 1
SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS NVARCHAR(10));
EXEC (@command);
PRINT N'Executed: ' + @command;
END;
-- Close and deallocate the cursor.
CLOSE partitions;
DEALLOCATE partitions;
-- Drop the temporary table.
DROP TABLE #work_to_do;
GO
E. Använd sys.dm_db_index_physical_stats för att visa antalet sidkomprimerade sidor
I följande exempel visas hur du visar och jämför det totala antalet sidor med de sidor som är rad- och sidkomprimerade. Den här informationen kan användas för att fastställa den fördel som komprimering ger för ett index eller en tabell.
SELECT o.name,
ips.partition_number,
ips.index_type_desc,
ips.record_count,
ips.avg_record_size_in_bytes,
ips.min_record_size_in_bytes,
ips.max_record_size_in_bytes,
ips.page_count,
ips.compressed_page_count
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED') ips
INNER JOIN sys.objects o
ON o.object_id = ips.object_id
ORDER BY record_count DESC;
F. Använda sys.dm_db_index_physical_stats i SAMPLED-läge
I följande exempel visas hur SAMPLED
-läget returnerar en ungefärlig som skiljer sig från resultatet för DETAILED
läge.
CREATE TABLE t3 (
col1 INT PRIMARY KEY,
col2 VARCHAR(500)
)
WITH (DATA_COMPRESSION = PAGE);
GO
BEGIN TRANSACTION
DECLARE @idx INT = 0;
WHILE @idx < 1000000
BEGIN
INSERT INTO t3 (col1, col2)
VALUES (
@idx,
REPLICATE('a', 100) + CAST(@idx AS VARCHAR(10)) + REPLICATE('a', 380)
)
SET @idx = @idx + 1
END
COMMIT;
GO
SELECT page_count,
compressed_page_count,
forwarded_record_count,
*
FROM sys.dm_db_index_physical_stats(db_id(), object_id('t3'), NULL, NULL, 'SAMPLED');
SELECT page_count,
compressed_page_count,
forwarded_record_count,
*
FROM sys.dm_db_index_physical_stats(db_id(), object_id('t3'), NULL, NULL, 'DETAILED');
G. Fråga service broker-köer för indexfragmentering
gäller för: SQL Server 2016 (13.x) och senare versioner
I följande exempel visas hur du frågar serverköer om fragmentering.
--Using queue internal table name
SELECT *
FROM sys.dm_db_index_physical_stats(db_id(), object_id('sys.queue_messages_549576996'), DEFAULT, DEFAULT, DEFAULT);
--Using queue name directly
SELECT *
FROM sys.dm_db_index_physical_stats(db_id(), object_id('ExpenseQueue'), DEFAULT, DEFAULT, DEFAULT);
Relaterat innehåll
- Vyer för dynamisk hantering av system
- Index related Dynamic Management Views and Functions (Transact-SQL)
- sys.dm_db_index_operational_stats (Transact-SQL)
- sys.dm_db_index_usage_stats (Transact-SQL)
- sys.dm_db_partition_stats (Transact-SQL)
- sys.allocation_units (Transact-SQL)
- Transact-SQL referens (databasmotor)