web-dev-qa-db-ja.com

クラスター化列ストアインデックスの暗号化されたデータのパフォーマンスへの影響

私はSQL Server 2016を使用しており、パフォーマンスの観点から以下の点に関する詳細を期待しています。

  1. クラスター化列ストアインデックスが既に作成されているのと同じテーブルに主キー-一意制約を作成することで、パフォーマンスの向上や追加の利点はありますか?

  2. テーブルに暗号化された列が含まれている場合(10列のうち9列は暗号化されています)、クラスター化列ストアインデックスを作成する場合に利点はありますか?使ってます SYMMETRIC KEY暗号化用。

2
Aftab Ansari

可能であれば、1つの質問で複数の無関係な質問をすることは避けてください。あなたの最初の質問は非常に広いです。一般に、インデックスの作成は常にトレードオフであり、一部のクエリはそのインデックスの恩恵を受けます。列ストアテーブルのNCIについても同様です。代わりに2番目の質問に焦点を当てます。

私の知る限り、SYMMETRIC KEYによる暗号化は、列ストアに非常によく一致しません。暗号化されたデータをCCIに挿入するということは、長くて比較的ユニークな文字列をvarbinary列に挿入するということです。 CCIは、これらのデータ型とデータ分布ではうまく機能しません。行グループのサイズを制限するディクショナリのプレッシャーにぶつかる可能性が高く、列の削除を除いて、列ストアのほとんどの機能を利用できなくなります。

私は 対称キーでSQL Server暗号化を使用する方法 のコードを見つけて、簡単な例を開発しました。データがどのように見えるかわからないので、テーブルに一意の整数を挿入し、同じ一意の整数を暗号化して別のテーブルに挿入します。キーの定義:

CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'you will never guess this';

CREATE CERTIFICATE MyFirstCertificate
WITH SUBJECT = 'no u';

CREATE SYMMETRIC KEY key_to_answering_217242 WITH
IDENTITY_VALUE = 'yeah nah',
ALGORITHM = AES_256,
KEY_SOURCE = 'closet full of jandals'
ENCRYPTION BY CERTIFICATE MyFirstCertificate;

2つのテーブルを作成し、両方にデータを挿入するT-SQL:

DROP TABLE IF EXISTS dbo.CCI_NOT_ENCRYPTED;

CREATE TABLE dbo.CCI_NOT_ENCRYPTED (
ID BIGINT,
INDEX CCI CLUSTERED COLUMNSTORE
);

INSERT INTO dbo.CCI_NOT_ENCRYPTED WITH (TABLOCK)
SELECT TOP (1048576) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
OPTION (MAXDOP 1);

GO

USE master;
GO

OPEN SYMMETRIC KEY key_to_answering_217242
DECRYPTION BY CERTIFICATE MyFirstCertificate


DROP TABLE IF EXISTS [TEST].dbo.CCI_ENCRYPTED;

CREATE TABLE [TEST].dbo.CCI_ENCRYPTED (
ID VARBINARY(256),
INDEX CCI CLUSTERED COLUMNSTORE
);

INSERT INTO [TEST].dbo.CCI_ENCRYPTED WITH (TABLOCK)
SELECT EncryptByKey(Key_GUID('key_to_answering_217242'), CAST(RN AS VARCHAR(7)))
FROM (
    SELECT TOP (1048576) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
    FROM master..spt_values t1
    CROSS JOIN master..spt_values t2
) q
OPTION (MAXDOP 1);

CLOSE SYMMETRIC KEY key_to_answering_217242;

GO

テーブルの合計サイズには明らかな違いがあります。暗号化されたデータを含むテーブルは、20倍以上大きくなります。

size difference

sys.dm_db_column_store_row_group_physical_statsを見ると、暗号化されたデータを含むテーブルの行グループのサイズは、辞書の圧力によって制限されていることがわかります。

dict pressure

もちろん、クエリのパフォーマンスも大幅に影響を受けます。次のクエリのCPU時間は約0ミリ秒です。

SELECT COUNT(*)
FROM dbo.CCI_NOT_ENCRYPTED
WHERE ID = 1;

暗号化されたテーブルで同じクエリを実行すると:

USE master;
GO

OPEN SYMMETRIC KEY key_to_answering_217242
DECRYPTION BY CERTIFICATE MyFirstCertificate

SELECT COUNT(*)
FROM [TEST].dbo.CCI_ENCRYPTED
WHERE CAST(CAST(DecryptByKey(ID) AS VARCHAR(7)) AS BIGINT) = 1;

CLOSE SYMMETRIC KEY key_to_answering_217242;

GO

CPU時間は600ミリ秒以上かかります。以上のことすべてを踏まえると、暗号化されたデータを処理する場合、一般に大きなオーバーヘッドが発生するようです。列ストアが正確なデータとシナリオにメリットをもたらすかどうかはわかりませんが、列ストアの通常のメリットが確実に見られるわけではありません。

3
Joe Obbish

これは、列ストアインデックスの奇妙なケースのように思えます。とにかく:

1:列ストアインデックスの場合、データの圧縮とpossliblyセグメントの削除が行われます。ただし、列ストアインデックスにはシークなどはありません。そのため、これらの列で選択性の高い検索を行うクエリがあり、パフォーマンスが重要である場合、はい-行インデックス(PKおよびUQに付属)があると有益です。

2:「暗号化された」という意味ではなく、「暗号化されていない」という意味ですか?使用しているテクノロジはわかりませんが、データがクリアテキストではないため、SQL Serverがクエリを支援するためにできることはほとんどないため、列ストアがここで役立つとは思えません。しかし、私たちが続ける情報はほとんどありません...

1
Tibor Karaszi