Data Compression

Falls es auf der Platte mal eng wird, kann man mit Data-Compression (Daten-Komprimierung) einige Objekte verkleinern und wieder Platz schaffen. Allerdings setzt dieses Feature die Enterprise Edition vorraus.
Doch sollte man nicht übersehen, dass der eigentliche Vorteil dieser Option darin besteht, das IO-Geschäft zu beschleunigen und damit den Abfragen, die sich mit großen Tabellen beschäftigen mal etwas Beine zu machen.

Vorraussetzung für den sinnvollen Einsatz von Data-Compression ist aber nicht nur die Enterprise Edition, sondern auch noch verfügbare CPU-Zeit, da Data-Compression das IO-Geschäft durch eine erhöhte Rechenleistung reduziert.

In meinem Produktionsumfeld gab es einen Join über 23 Tabellen, von denen jede ca. 2 GB groß war. Das Ergebnis dieses Joins waren ca. 15 GB, die in eine neue Tabelle geschrieben wurden. Der Server verfügt über 32 GB RAM. Normalerweise benötigte diese Abfrage ca. 14 Stunden und die CPU-Belastung währenddessen kam über 10% kaum hinaus. Wir haben dies nun so umgestellt, dass alle zugrundeliegenden Tabellen auf PAGE-Ebene komprimiert werden. Die Abfrage benötigt jetzt weniger als zwei Stunden und die CPU-Belastung lag bei ca. 30%.

In der Online-Doku gibt es ausführliche Informationen zur Komprimierung. Hier möchte ich nur einige wenige Code-Schipsel beitragen um mal die Richtung vorzugeben:
Welche Objekte gibt es und wie ist die Komprimierung eingestellt?

SELECT o.OBJECT_ID,
      
S.name AS [schema],
      
o.name AS [Object],
      
I.index_id AS Ix_id,
      
I.name AS IxName,
      
I.type_desc AS IxType,
      
P.partition_number AS P_No,
      
P.data_compression_desc AS Compression
    
FROM sys.schemas AS S
      
JOIN sys.objects AS O
        
ON S.schema_id = O.schema_id
      
JOIN sys.indexes AS I
        
ON o.OBJECT_ID = I.OBJECT_ID
      
JOIN sys.partitions AS P
        
ON I.OBJECT_ID = P.OBJECT_ID
        
AND I.index_id= p.index_id
    
WHERE O.TYPE = 'U'
    
ORDER BY [schema], [object], i.index_id;

Welche Einsparungen habe ich bei der einen oder anderen Komprimierungs-Methode zu erwarten?

EXEC sp_estimate_data_compression_savings 'dbo','meineTabelle',NULL,NULL,'PAGE';
EXEC sp_estimate_data_compression_savings 'dbo','meineTabelle',NULL,NULL,'ROW';

Wie kann ich Objekte komprimieren?

ALTER TABLE dbo.meineTabelle rebuild WITH (data_Compression = PAGE);
-- Indizes
ALTER INDEX IX_meineTabelle_1 ON dbo.meineTabelle rebuild WITH (data_Compression = PAGE);

Die Daten-Komprimierung ist also neben Indizes eine weitere Möglichkeit Abfragen zu beschleunigen, indem die IO-Last reduziert wird.

  • *****
    Kommentar von: Torsten Schuessler
    14.07.10 @ 08:30:52

    Hallo Christoph,

    wie verhalten sich die E/A's bei einem Rebuild der komprimierten Indizes?

    Anbei noch ein kleiner Link zu Paul Nielsen: http://www.sqlserverbible.com/files/ch73datacompression.sql

    Ich wünsche Dir einen schönen Tag,

    Torsten

  • Kommentar von: Christoph Muthmann
    14.07.10 @ 15:08:50

    Der Rebuild der Indizes ist schon interessant:
    alter index meinIndex on dbo.meineTabelle rebuild;
    3280 Pages compressed/sec
    2476 Page Writes/Sec
    41 Sekunden

    Ohne Komprimierung:

    alter index meinIndex on dbo.meineTabelle rebuild;
    13971 Page Writes/Sec
    18 Sekunden

  • *****
    Kommentar von: Torsten Schuessler
    14.07.10 @ 16:15:35

    :-) das hast Du nach meinem Post ausprobiert! Ha!
    Jetzt fehlt nur noch die Reorganisation von Indizes :-)

  • Kommentar von: Christoph Muthmann
    15.07.10 @ 08:21:27

    Auch beim Reorganize ist der Index mit Komprimierung langsamer (30 Sekunden gegenüber 24 Sekunden ohne Komprimierung). Die Page Writes/sec schnellten in beiden Fällen kurzzeitig mal auf ca. 30.000 hoch.

  • *****
    Kommentar von: Torsten Schuessler
    15.07.10 @ 11:03:59

    Hallo Christoph,

    was mich jetzt noch interessieren würde ist das Storage - SAN? Welches? Wie konfiguriert? Blockgrösse?
    Fragen über Fragen :-)

    Ich wünsche Dir einen schönen Tag,

    Torsten

  • Kommentar von: Christoph Muthmann
    15.07.10 @ 11:08:53

    Aktuell hat der Server noch interne Platten. Zwei interne RAID1 Systeme. 2 Quad Core CPUs mit HyperThreading, 32 GB RAM (MaxMemory 28 GB), SQL Server 2008R2 und nur ein Anwender! ;-)

    SAN kommt erst morgen und dann bin ich nicht mehr alleine auf dem Teil!

    SAN wird bei uns immer mit 64 KB Blockgrösse definiert.

  • *****
    Kommentar von: Torsten Schuessler
    15.07.10 @ 14:25:01

    ... SAN Hersteller?
    wider ein RAID1 auf der SAN?

Einen Kommentar hinterlassen

Ihre E-Mail-Adresse wird nicht auf dieser Seite angezeigt.
SchlechtExzellent
(Zeilenumbrüche werden zu <br />)
(For my next comment on this site)
(Allow users to contact me through a message form -- Your email will not be revealed!)
Dies ist ein Captcha Bild. Es wird benutzt, um Massenzugriffe von Robotern zu verhindern.
Bitte gib die Zeichen des obigen Bildes ein. (Groß/Kleinschreibung ist wichtig)
Trackback-Adresse für diesen Eintrag
Dies ist ein Captcha Bild. Es wird benutzt, um Massenzugriffe von Robotern zu verhindern.
Bitte gib die Zeichen des obigen Bildes ein. (Groß/Kleinschreibung ist wichtig)