Bieten BIT-Spalten Leistungsvorteile für CCIs?


7

Do BITSpalten bieten alle Vorteile Leistung , wenn in Clustered Columns Indizes verwendet? Ich bin an Leistungsvorteilen interessiert, die sich aus der Definition einer Spalte in einer IHK ergeben, BITanstatt BIGINTbeispielsweise. Ich arbeite mit SQL Server 2016.

Ich habe ein sehr begrenztes Verständnis der Funktionsweise der CCI-Komprimierung, aber basierend auf dem, was ich gelesen und getestet habe, scheint es, dass der Datentyp (beschränkt auf exakte Zahlen, in denen ganze Zahlen gespeichert sind) bei der Spaltenspeicherkomprimierung keine Rolle spielen sollte . Wenn ich beispielsweise 10 vollständige Zeilengruppen in Tabellen mit BIGINTSpalten im Gegensatz zu BITSpalten einfüge, wird kein Größenunterschied zwischen den komprimierten Zeilengruppen angezeigt. Hier sind die Quelldaten für einen Test:

DROP TABLE IF EXISTS dbo.CCI_BIT_TEST_SOURCE;

CREATE TABLE dbo.CCI_BIT_TEST_SOURCE (
    ID1 BIGINT NOT NULL,
    ID2 BIGINT NOT NULL,
    ID_BIT BIT NOT NULL,
    ID_BIGINT BIGINT NOT NULL,
    INDEX CCI__CCI_BIT_TEST_SOURCE CLUSTERED COLUMNSTORE
);

INSERT INTO dbo.CCI_BIT_TEST_SOURCE WITH (TABLOCK)
SELECT
  t.RN
, t.RN
, t.RN % 2
, t.RN % 2
FROM
(
    SELECT TOP (10485760) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
    FROM master..spt_values t1
    CROSS JOIN master..spt_values t2
    CROSS JOIN master..spt_values t3
) t
OPTION (MAXDOP 1);

Das Einfügen in eine CCI mit 8 BITSpalten dauerte durchschnittlich 18729 ms CPU-Zeit. Die Tabelle verfügt über 56960 KB reservierten Speicherplatz:

DROP TABLE IF EXISTS dbo.CCI_BIT;

CREATE TABLE dbo.CCI_BIT (
    ID1 BIGINT NOT NULL,
    ID2 BIGINT NOT NULL,
    ID_BOOL_1 BIT NOT NULL,
    ID_BOOL_2 BIT NOT NULL,
    ID_BOOL_3 BIT NOT NULL,
    ID_BOOL_4 BIT NOT NULL,
    ID_BOOL_5 BIT NOT NULL,
    ID_BOOL_6 BIT NOT NULL,
    ID_BOOL_7 BIT NOT NULL,
    ID_BOOL_8 BIT NOT NULL,
    INDEX CCI__CCI_BIT CLUSTERED COLUMNSTORE
);

INSERT INTO dbo.CCI_BIT WITH (TABLOCK)
SELECT
  ID1
, ID2
, ID_BIT
, ID_BIT
, ID_BIT
, ID_BIT
, ID_BIT
, ID_BIT
, ID_BIT
, ID_BIT
FROM dbo.CCI_BIT_TEST_SOURCE
OPTION (MAXDOP 1);

Das Einfügen in eine CCI mit 8 BIGINTSpalten dauerte durchschnittlich 18531 ms CPU-Zeit. Die Tabelle verfügt über 56960 KB reservierten Speicherplatz, wie zuvor:

DROP TABLE IF EXISTS dbo.CCI_NO_BIT;

CREATE TABLE dbo.CCI_NO_BIT (
    ID1 BIGINT NOT NULL,
    ID2 BIGINT NOT NULL,
    ID_BOOL_1 BIGINT NOT NULL,
    ID_BOOL_2 BIGINT NOT NULL,
    ID_BOOL_3 BIGINT NOT NULL,
    ID_BOOL_4 BIGINT NOT NULL,
    ID_BOOL_5 BIGINT NOT NULL,
    ID_BOOL_6 BIGINT NOT NULL,
    ID_BOOL_7 BIGINT NOT NULL,
    ID_BOOL_8 BIGINT NOT NULL,
    INDEX CCI__CCI_NO_BIT CLUSTERED COLUMNSTORE
);

INSERT INTO dbo.CCI_NO_BIT WITH (TABLOCK)
SELECT
  ID1
, ID2
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
, ID_BIGINT
FROM dbo.CCI_BIT_TEST_SOURCE
OPTION (MAXDOP 1);

Wir können dies auch in den Columnstore-DMVs sehen:

cci dmvs

Die Verwendung von BITSpalten in CCIs bietet einige Vorteile . Beispielsweise nehmen in Delta-Speicher geladene Daten mit BITSpalten weniger Platz ein , da Delta-Speicher im Grunde genommen unkomprimierte Heaps sind. In Abfrageplänen basiert die Formel für die geschätzte Datengröße auf den Datentypen der Spalten im Gegensatz zur Größe der Tabelle auf der Festplatte. Die Tabelle mit BITSpalten hat eine Gesamtdatengröße von 250 MB und die Tabelle mit BIGINTSpalten hat eine Gesamtdatengröße von 880 MB. In einigen Fällen könnte die geschätzte Größe von 250 MB zu einem besseren Plan führen.

Gibt es weitere Leistungsvorteile von BITSpalten für CCIs? Oder hat geben die Daten nicht wirklich egal, solange Sie eine exakte numerische dass speichert ganze Zahlen verwenden ( BIT, TINYINT, SMALLINT, INT, oder BIGINT)?


Nicht gerade eine Antwort auf Ihre Frage zu Vorteilen, aber ein Nachteil, den Sie möglicherweise in Betracht ziehen: Aggregate wie MIN / MAX / SUM werden nicht unterstützt BIT. Sie müssen also verwenden CONVERT, um eine solche Aggregation durchzuführen, und diese Konvertierung verhindert das Pushdown von Aggregaten. Wenn Sie versuchen , eine nehmen MINauf ID_BOOL_1auf Ihre beiden Tabellen, ich glaube , Sie werden feststellen , dass die BIGINTVersion tatsächlich wesentlich schneller aus diesem Grunde ist!
Geoff Patterson

1
@GeoffPatterson Das ist eigentlich die Motivation für diese Frage. Ich mag die eingeschränkte Syntax für BIT-Spalten und daher die mangelnde Unterstützung für aggregiertes Pushdown nicht. Vielleicht kann bei einigen Rowstore-Tabellen die Platzersparnis durch BIT-Spalten nicht ignoriert werden, aber ich möchte sie nicht in CCIs aufnehmen.
Joe Obbish

Antworten:


2

Erstens vergleichen wir keine ähnlichen Datentypen.

Bit ist definiert als:

Ein ganzzahliger Datentyp, der den Wert 1, 0 oder NULL annehmen kann.

BISSCHEN

Während BIGINT eine größere Ganzzahl ist, die standardmäßig viel Speicherplatz beansprucht.

Das bedeutet, dass SQL Server standardmäßig Statistiken zu jeder der BIT-Spalten und nur einen Satz für den BIGINT hat.

Wie Sie zu Recht bemerkt haben, werden BIT-Spalten optimiert:

Das SQL Server-Datenbankmodul optimiert die Speicherung von Bitspalten. Wenn eine Tabelle 8 oder weniger Bitspalten enthält, werden die Spalten als 1 Byte gespeichert. Wenn 9 bis 16-Bit-Spalten vorhanden sind, werden die Spalten als 2 Byte usw. gespeichert.

int, bigint, smallint und tinyint

Es muss einen Grund geben, warum Sie sogar in Betracht ziehen, mindestens 8 - 10 Binärwerte in eine numerische Zahl umzuwandeln.

Warum sollte man nur INT verwenden und die Hälfte des Platzes sparen? Seit ich das letzte Mal nachgesehen habe, sind 2.147.483.648 10 Zeichen für nur 4 Bits und BIGINT hat ungefähr 19, was technisch gesehen weniger Platz als BIT von youvspoit ist, als in Spalten.

Dies verliert jedoch den Überblick über Ihre Daten . Wie beantwortet BIT Fragen zu dem, was es darstellt? 10010 ist nur eine Zahl größer als zehntausend und doch binär, was tatsächlich etwas darstellt. Wenn Sie unter "Speichern" Speicherplatz die Transformation erzwingen, bevor Sie die Daten überhaupt verwenden, ist sie dann immer noch effizient?

Bitte verbinden Sie BIT nicht mit einem numerischen Datentyp wie Tinyint oder BIGINT. Sie dienen zwei verschiedenen Zwecken.


1

Leistungsvorteile von CCIs sind nicht nur platzbezogen: Der Batch-Ausführungsmodus dient auch dazu, die Arbeit zu beschleunigen (bei unterstützten Operatoren).

Die Stapelgrößen können zwischen 64 und 900 Zeilen variieren. Es ist daher zu erwarten, dass die Verwendung kleinerer Datentypen zu "volleren" Stapeln führt, die näher an der maximalen Zahl von 900 liegen.

https://blogs.msdn.microsoft.com/sql_server_team/columnstore-index-performance-batchmode-execution/

Mit Datentypen sparsam umzugehen ist sowieso eine gute Angewohnheit - warum sollte man bigint in Betracht ziehen, wenn tinyint (oder bit) den Job machen würde?


1
Bit unterstützt keine Aggregate, daher unterstützt es kein Aggregat-Pushdown. Haben Sie eine Beispielabfrage, die beim Austauschen einer BIGINT-Spalte gegen ein BIT eine größere Stapelgröße anzeigt, oder ist das nur theoretisch?
Joe Obbish
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.