web-dev-qa-db-ja.com

大規模な列ストアインデックステーブルの再構築-正しく実行されていますか?

データベースをSQL 2014 ENTから2016 ENTに移動する予定です。現在columnstoreテーブルにあるデータは、読み込まれたときに時間的に整列されていないため、データを再整列する必要があることに気付きました。

統計:

  • 3つの大きなテーブル(インデックス付きの列ストア)
  • 大きなテーブルには600億行以上の行があります
  • 4つのデータファイル(ラウンドロビン)
  • 毎月分割
  • SQL Server 2014 ENT、128 GB RAM
  • 高性能VMプラットフォーム、32 CPU

ファイルグループ/データファイル:

  • 一次
  • DATA(4つのデータファイル、各データファイルは2TBディスク)
  • ログ

パーティションの詳細:

  • 月次パーティション機能
  • DATA FGのすべてのパーティションスキーム

テーブルサイズ(#行):

  • T1 34,807,580,311
  • T2 16,458,306,369
  • T3 10,170,792,290

私がやろうとしていること:

  • 列ストアインデックスを削除し、行ストアインデックスを作成します(これは、logtimeでデータを整列させるためです)
  • 次に、行ストアインデックスを削除し、テーブルを列ストアインデックスに変換します(後で圧縮とクエリを改善します)

再構築に非常に長い時間がかかるのではないかと心配しています。私は正しいアプローチを取っていますか?

DDL:

CREATE TABLE [dbo].[T1](
[Id] [int] NOT NULL,
[C1] [smallint] NOT NULL,
[C2] [int] NOT NULL,
[C3] [int] NOT NULL,
[C4] [int] NOT NULL,
[C5] [datetime2](0) NOT NULL,
[C6] [real] NULL,
[C7] [real] NULL,
[C8] [real] NULL,
[C9] [real] NULL,
[C10] [real] NULL,
[C11] [datetime2](3) NULL,
[C12] [tinyint] NULL
) ON [DATA]

CREATE CLUSTERED COLUMNSTORE INDEX [T1_ColumnStoreIndex] ON [T1]

CREATE TABLE [dbo].[T2](
    [C1] [int] NOT NULL,
    [C2] [smallint] NOT NULL,
    [C3] [int] NOT NULL,
    [C4] [int] NOT NULL,
    [C5] [int] NOT NULL,
    [C6] [datetime2](0) NOT NULL,
    [C7] [real] NULL,
    [C8] [int] NULL,
    [C9] [int] NULL,
    [C10] [tinyint] NULL,
    [C11] [tinyint] NULL,
    [C12] [tinyint] NULL
) ON [DATA]

CREATE CLUSTERED COLUMNSTORE INDEX [T2_ColumnStoreIndex] ON [T2]

CREATE TABLE [dbo].[T3](
    [C1] [int] NOT NULL,
    [C2] [smallint] NOT NULL,
    [C3] [int] NOT NULL,
    [C4] [int] NOT NULL,
    [C5] [int] NOT NULL,
    [C6] [datetime2](0) NOT NULL,
    [C7] [real] NULL,
    [C8] [real] NULL,
    [C9] [real] NULL,
    [C10] [real] NULL,
    [C11] [real] NULL,
    [C12] [real] NULL,
    [C13] [real] NULL,
    [C14] [varchar](50) NULL,
    [C15] [datetime] NULL,
    [C16] [int] NULL,
    [C17] [int] NULL,
    [C18] [float] NULL,
    [C19] [tinyint] NULL,
    [C20] [tinyint] NULL,
    [C21] [datetime2](3) NULL,
    [C22] [tinyint] NULL
) ON [DATA]

CREATE CLUSTERED COLUMNSTORE INDEX [T3_ColumnStoreIndex] ON [T3]

これはQ&Aではないかもしれませんが、ここで貴重な情報を得ることができると信じています。

3
rdagumampan

私がやろうとしていること:•列ストアインデックスを削除し、行ストアインデックスを作成します(これはデータをlogtimeで整列させるためです)。次に、行ストアインデックスを削除し、テーブルを列ストアインデックスに変換します(後で圧縮とクエリを改善します)。

CREATE CLUSTERED INDEX...WITH (DROP_EXISTING=ON)を使用して既存の列ストアのクラスター化インデックスをBツリーに変更し、次にCREATE CLUSTERED COLUMNSTORE INDEX...WITH (DROP_EXISTING=ON)を使用して列ストアに戻すことができます。これにより、列ストアをヒープに変更するインデックスの削除手順が不要になります。

600億行の場合、これにはかなり時間がかかると私はまだ予想しています。ソースデータはC6の順序で読み込まれなかった可能性がありますが、データ全体は通常、おおまかに年代順に読み込まれるため、同じ近接のデータには時間的な関係が存在します。 sys.column_store_segmentsの最小値と最大値を確認して、パーティションの削除後にセグメントの削除が行われることを考慮して、この作業が正当化されるかどうかを確認することをお勧めします。パフォーマンスのメリットは、思ったほど大きくないかもしれません。

1
Dan Guzman

以下に提供する詳細は、検討している操作の継続時間を調査するために設計された封筒の裏側の計算に基づいており、システムがどのように動作するかを正確に知ることは非常に難しいため、福音と見なすべきではありません。

T1はデータの行ごとに88バイトで、行のオーバーヘッドを除いて、すべてのnull許容列はnull以外です。 200億行で(eachテーブルに600億行あるか、またはすべて3つ)、これにより、テーブルは1.678になりますTB追加のインデックスや行/ページのオーバーヘッドなし、圧縮なし。

3GB /秒で実行されている非常に高速なローカルPCIe NVMe SSDを使用している場合でも、データを読み取るだけで約10分かかります。これは、特に索引の再編成または再構築時に発生することのない順次アクセスを想定しているため、絶望的に楽観的です。ローカルPCIe NVMe SSDで行われるランダムな64KB転送のより妥当な転送速度は、300MB /秒の範囲になります。その速度では、1.678 TBテーブルを読み取るだけで約93分かかります。余裕があれば、WITH (DROP_EXISTING = ON)、ただし、別のディスクサブシステムに存在する、新しく作成されたファイルグループに作成される新しいインデックスも定義します。非常に高速なディスクサブシステムを使用しても、少なくとも数時間は表示されます。 1つのテーブルを再編成します。ストレージがローカルSSDにない場合、かかる時間は上記で提供した数値の倍数になります。

停止ウィンドウの最大期間に応じて、 パーティションごとに複数の停止ウィンドウにわたってパーティションごとに再構築 を実行することを検討します。

テーブルの単一のint列に非クラスター化列ストアインデックスがあり、圧縮率が50%であると仮定すると、200億行はインデックスごとに少なくとも38 GBを消費します。列ストア構成の詳細を提供していません。そうすれば、より正確な見積もりが得られます。

0
Max Vernon