web-dev-qa-db-ja.com

クラスター化列ストアインデックスを含むテーブルに新しい列を追加する

毎日のファクトテーブルがあります 'FactsTable1 'は240列あり、ここで' Clustured Columnstore Index '(CCI)。

私は知りたいです、

  • さらに50列をテーブルに追加するとどうなりますか?
  • それらは自動的にCCIに追加されますか?または、もう一度CCIを再構築する必要がありますか?
  • そのような状況に対処するための最良の方法は何でしょうか?
  • 新しい列をCCIの一部にするためにインデックスを再構築する必要がある場合、再構築しないとどうなりますか?クエリのパフォーマンスにどのように影響しますか?

追加情報:

  • FactsTable1には400000+行と240列が含まれています
  • 日付列で分割されている
  • 分析データの問い合わせが頻繁に行われます。
  • @@ version:Microsoft SQL Server 2016(RTM)-13.0.1601.5(X64)
1
Ketan

さらに50列をテーブルに追加するとどうなりますか?

デフォルト値を指定していない場合、これらの列はNULL値とともにテーブルに追加されます。デフォルト値を追加した場合、圧縮された行グループはそのまま残り、更新は行われません。

自動的にCCIに追加されますか?

はい

そのような状態を処理するための最良の方法は何ですか?

新しい列のすべての値を更新する場合は、削除された行が多く、デルタストア(ヒープ)が開いている多数の圧縮された行グループを取得します。閉じているとマークされている場合、圧縮セグメントに格納します(サイズ1 000 000行)。数行しか残っていない圧縮セグメントを取り除くには、REORGANIZEステートメントを実行する必要があります

追加情報

-> CCIを適切に機能させるには、少なくとも1 000 000行が必要です。そうしないと、ヒープデルタストアでスタックします。 (400 000しかない)

これには、すべての行を圧縮セグメントに入れるために、インデックスの再構築または再編成を行う必要があります

ALTER INDEX idx_cci_target ON cci_target REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);

SQL Server 2016をSP1にアップグレードする必要もあります

これを試してください

ファクトテーブルにはそれほど多くの行がないため、NCCIトリックを使用した方がよい場合があります。テーブルに空のフィルター処理された非クラスター化列ストアインデックスを作成できます。これにより、テーブルのコストはゼロになりますが、バッチモードの実行プランがトリガーされ、分析クエリで多くのメリットが得られます。

CREATE NCCI_TEST on TESTABLE (ALL COLUMNS)
WHERE ID = -1 and ID = -2

CREATE TABLE dbo.test
(
Bla datetime,
blabla varchar(200)
)
GO
CREATE CLUSTERED COLUMNSTORE INDEX CCI_TEST on DBO.TEST
GO

そして、いくつかの行を挿入します

INSERT INTO dbo.test
select DATEADD(day, (ABS(CHECKSUM(NEWID())) % 65530), 0),cast(ABS(CHECKSUM(NEWID())) as varchar)
GO 10000

insert into dbo.test
select * from dbo.test
GO 5

次に行って、列ストア要素を確認します

select * from sys.column_store_row_groups

RowstoreElements

これでデルタストアが作成されたことがわかります。つまり、これはインデックスのないヒープテーブルです。

次に、すべての行グループを圧縮してインデックスを再構築する場合

ALTER INDEX CCI_TEST on DBO.TEST REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON)

Compressed

tombstone要素は、以前のdeltastore/compressedセグメントであり、約5分後に削除されます

これで、列ストアの圧縮が行われました(これにより、ロックの問題が回避されます)

新しい列を追加すると

alter table dbo.test add nondefaultvalue varchar(20)

行グループをもう一度確認します

StillCompressed

行グループのレイアウトは適切です。

デフォルト値を持つ別の列を追加し、行グループを確認すると

alter table dbo.test add defaultvalue varchar(20) not null default('DEFAULT')

Rowgroups still

ただし、これらの値を更新することを決定した場合。

UPDATE dbo.test 
set nondefaultvalue = 'DEFAULT'

物事が変わる

OpenDeltastore

使用できる圧縮セグメントはもうありません。次に、このインデックスを再編成しようとすると

ALTER INDEX CCI_TEST on DBO.TEST REORGANIZE

Reorganizeafterupdate

開いているデルタストアを再度取得すると、ロックが発生します。ただし、前に見た次のコマンドを発行することで、圧縮されたセグメントに戻すことができます。

ALTER INDEX CCI_TEST on DBO.TEST REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON)

recompressed

今度は、列ストアセグメントを再び適切にする必要があります。

したがって、あなたのケースでは、すべての行グループを圧縮して再編成し、正常に機能させる必要があります。これは、400 000行しかないテーブルでは時間がかかりませんが、ロックを回避する必要があります。

一括挿入を行うと、ストーリーの変更が再度挿入されますが、すべてを圧縮セグメントに直接入れるには、一度に100 000行を実行する必要があります。

辞書

別の列を追加すると、新しいディクショナリが列ストアインデックスに対して作成されます(列ストアセグメント内の列要素への一種のマッピング)。

select * from sys.column_store_dictionaries

alter table dbo.test add defaultvalue2 varchar(20) not null default('DEFAULT')

select * from sys.column_store_dictionaries

Dictionaries

詳細については、 http://www.nikoport.com/ にアクセスすることをお勧めします。彼は、ブログのcolumnstoreに必要なすべての追加情報を提供しています。

6
Stijn Wynants