web-dev-qa-db-ja.com

SQLステージングテーブル:主キーのクラスター化またはヒープ

レガシーフラットtxtファイルを取得し、SSISを使用してステージテーブルに挿入しています。テーブルにプライマリクラスター化キーインデックスを含める必要があるかどうかという質問がありました。これは、変換なしの直接フラットファイルインポートです。

create table dbo.CustomerTransaction
(
     CustomerName varchar(255),
     PurchaseLocation varchar(255),
     Productid  int,
     AmountSold float,
     CustomerAddress varchar(50)
)

create table dbo.CustomerTransaction
(
     -- discussion for adding this column
     CustomerTransactionId int primary key clustered identity(1,1) 

     CustomerName varchar(255),
     PurchaseLocation varchar(255),
     Productid  int,
     AmountSold float,
     CustomerAddress varchar(50)
)

-- both tables have nonclustered indexes
create nonclustered index idx_ProductId on dbo.CustomerTransaction(ProductId)
create nonclustered index idx_CustomerAddress on dbo.CustomerTransaction(CustomerAddress)

-- Actually have more indexes, tables above are just for sample 

1)ETLの前に、ステージングテーブルは切り捨てられます。削除や更新はありません。インサートのみ。

truncate table dbo.[CustomerTransaction]

2)次に、ETLの前にすべてのインデックスを無効にします。

alter index all on dbo.[CustomerTransaction] DISABLE

3)デフォルトの高速ロードでSSISデータフローを実行します。これは、一括挿入と同じです。ここでは変換は発生しません。

4)インポートが完了したら、すべてのインデックスを再度有効にします。

alter index all on dbo.[CustomerTransaction] REBUILD

5)次に、ステージングテーブルが結合句と場所句で選択され、データウェアハウスに配置されます。これが、非クラスター化インデックスがある理由です。データウェアハウスが読み込まれた後、ステージングテーブルを切り捨てます。

ETLステージテーブルはヒープとして適しているという情報を聞いています。ただし、ヒープの断片化とパフォーマンスの問題についても学習します。以下のすべての記事を読む

私は矛盾する意見を読んでいます。 1つは、クラスター化されたバイナリツリーはインポートETLのメンテナンスの頭痛の種だと言います。他の人は、ヒープには断片化に関するパフォーマンスの問題があると言います。パフォーマンステストでは大きな違いは示されていませんが、データは後で変更される可能性があります。したがって、適切な設計決定を行う必要があります。

https://sqlsunday.com/2016/09/01/compelling-case-for-heaps/

https://www.mssqltips.com/sqlservertip/4961/sql-server-insert-performance-for-clustered-indexes-vs-heap-tables/

http://kejser.org/clustered-indexes-vs-heaps/

https://www.red-gate.com/simple-talk/sql/database-administration/sql-server-heaps-and-their-fragmentation/

IDを使用する正当な理由が行のラベル付けであることがわかっていますが、問題は主に内部とパフォーマンスに関するものです。

6
user162241

同様のシナリオがあり、最近、ステージングテーブルをクラスター化インデックスからヒープに切り替えました。私たちにとっての最初の大きな利点は、同じステージングテーブルへの同時SSISロードを許可することでした。クラスタ化インデックスを使用してこれを行うことができますが、特にID列を使用すると、多くのブロックが発生する可能性があります。 2番目の大きな利点は、ステージングテーブルをロードするオーバーヘッドを削減することでした。クラスター化されたインデックスと比較して、ヒープでのロードがはるかに高速であることがわかりました。

パフォーマンステストでは大きな違いは示されていませんが、データは後で変更される可能性があります。したがって、適切な設計決定を行う必要があります。

これは本当ですか?質問では、ロード前にステージングテーブルを切り捨てると言っています。ロードプロセスの一部が変更された場合、テーブルが空の間にクラスター化インデックスを追加または削除するのは非常に簡単です。関連するデータの移動はありません。クラスター化インデックスからメリットを得られるようには思えないので、ヒープとして試してパフォーマンスを監視します。

2
Joe Obbish

ID列があっても、それをクラスター化インデックスキーとして使用する必要はありません。

ヒープがここでうまく機能するのは正しいです。 Thomas Kejserはこの件に関する権威であると考えます。彼をリソースの1つとしてリストに登録していただければ幸いです。

ヒープの断片化について-挿入のみでは発生しません。

編集:並列挿入に関するこの記事を読み、ヒープとクラスター化インデックスの比較に注目してください。 https://blogs.msdn.Microsoft.com/sqlcat/2016/07/21/real-world-parallel-insert-what-else-you-need-to-know/

5
Rob Farley