it-swarm.com.de

Wie kann ich feststellen, ob die Daten in einer SQL Server-Tabelle seitenkomprimiert sind?

Dies ist eine Folgefrage zu einer Frage, die ich gestern gestellt habe: Kann ich eine Masseneinfügung in eine leere, seitenkomprimierte Tabelle vornehmen und eine vollständige Komprimierung erhalten? Die Antwort auf diese Frage (umschrieben von Randi Vertongens ausgezeichneter Antwort ) ist ja, erfordert jedoch, dass der Masseneinsatz eine Sperre auf Tabellenebene aufweist. Andernfalls nimmt die Masseneinfügung eine Sperre auf Zeilenebene vor und führt nur eine Zeilendatenkomprimierung durch. Dies wirft die Frage auf: Wie kann ich anschließend feststellen, welche Komprimierung angewendet wird?

Hier sind die Schritte zum Erstellen zeilenkomprimierter Daten in einer theoretisch seitenkomprimierten Tabelle:
1. Erstellen Sie eine Tabelle mit DATA_COMPRESSION=PAGE Und aktivieren Sie mit sp_tableoption Nicht die Option "Tabellensperre beim Massenladen" für diese Tabelle.
2. Verwenden Sie bcp, um die Daten aus einer Einfachdatei in die neue Tabelle einzufügen, ohne jedoch die Option -h TABLOCK Anzugeben, um die Tabelle zu sperren.

Das Ergebnis ist eine Tabelle, in der die Daten auf Zeilenebene komprimiert werden (kleiner als eine nicht komprimierte Tabelle, aber größer als eine seitenkomprimierte Tabelle). Wenn Sie jedoch die Katalogtabelle sys.allocation_units Überprüfen, wird die Datenkomprimierung als Seite angezeigt.

Die Frage

Wenn die Tabelle Datenzuordnung wie in diesem Szenario für die Seitenkomprimierung vorgesehen ist, was kann ich tun, um herauszufinden, ob die Daten in dieser Tabelle seitenkomprimiert ist?

7
Caitlin M. Shaw

Um zu sehen, ob Datenseiten tatsächlich "PAGE" -komprimiert sind oder nicht, können Sie das undokumentierte DMF sys.dm_db_database_page_allocations() verwenden. Das is_page_compressed Feld enthält die Informationen, die Sie suchen. Sie müssen den Modus DETAILED (d. H. Den 5. Parameter) verwenden, da sonst alle Werte in diesem Feld NULL sind.

Um klar zu sein (basierend auf dem Wortlaut der Frage: "Was kann ich tun, um herauszufinden, ob das Daten in dieser Tabelle seitenkomprimiert ist?"), Ist dies kein All-or- Kein Problem: Die Seitenkomprimierung wird angewendet pro Datenseite, daher können Sie keine komprimierte, alle komprimierte oder eine beliebige Kombination dazwischen haben. Sie müssen sich also alle Seiten ansehen. Und nein, Sie können nicht unbedingt davon ausgehen, dass eine einzelne nicht seitenkomprimierte Seite anzeigt, dass Sie REBUILD benötigen, da eine nicht gefüllte Seite nicht komprimiert wird.

Zum Beispiel:

SELECT [is_page_compressed]
FROM   sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID(N'dbo.CompressedHeap'),
                                           0, 1, 'DETAILED');

Das Folgende zeigt, dass die Datenseiten anfangs nicht seitenkomprimiert sind, sondern nach der Operation REBUILD:

USE [tempdb];

-- DROP TABLE dbo.CompressedHeap;
CREATE TABLE dbo.CompressedHeap
(
  ID INT IDENTITY(1, 1) NOT NULL,
  String sysname,
  [MaxLength] SMALLINT,
  [Type] VARCHAR(5)
) WITH (DATA_COMPRESSION = PAGE);


INSERT INTO dbo.CompressedHeap ([String], [MaxLength], [Type])
  SELECT col.[name], col.[max_length], obj.[type]
  FROM   master.sys.columns col
  CROSS JOIN master.sys.objects obj;


SELECT [is_page_compressed], *
FROM   sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID(N'dbo.CompressedHeap'),
                                           0, 1, 'DETAILED')
WHERE  [is_iam_page] = 0
AND    [is_allocated] = 1;
-- 394 pages


ALTER TABLE dbo.CompressedHeap REBUILD;


SELECT [is_page_compressed], *
FROM   sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID(N'dbo.CompressedHeap'),
                                           0, 1, 'DETAILED')
WHERE  [is_iam_page] = 0
AND    [is_allocated] = 1;
-- 179 pages
13
Solomon Rutzky

Die Komprimierungsstufe finden Sie in sys.partitions dmv

SELECT t.name AS tablename,
       i.name AS indexname,
       p.data_compression_desc
FROM sys.tables AS t
INNER JOIN sys.indexes AS i
     ON t.object_id = i.object_id
INNER JOIN sys.partitions AS p
     ON i.object_id = p.object_id
        AND i.index_id = p.index_id;
0
Bob Klimes