web-dev-qa-db-ja.com

パーティションを作成するとロックが削減されますか?これをSQLサーバーに実装するには

クライアントは、アプリケーションがより多くのデータをより速く処理することを望んでいるため、dbaとのミーティングを開いてオプションについて話し合いました。

このアプリケーションは、レポートに使用される大量のデータを生成します。各実行の前に、そのアイテムの古いデータが削除され、計算が実行されてから、新しいデータが挿入されます。繁忙期には、ユーザーがこれらの生成タスクを何百もキューに入れ、最大30を同時に実行します。実行ごとに60K行が作成される場合があります。

Dbaは、挿入と削除中のスレッド間のロックを減らすために、アプリケーションを30のパーティション(たとえば、スレッドごとに1つ)を使用するように変更できることを示唆しています。彼らは、標準のSQLで私たちは次のようなことができることを示唆しました

INSERT INTO schema.table.partition (...) VALUES (...)

msdn docs にこの構文がありません。これは、このアプリケーションを変更することを意味しますが、これは面倒ですが、これを行うことも可能ですか?私が理解しているように、代わりにパーティション関数を使用してテーブルの列に基づいてパーティションを作成しますか?

パーティション関数の作成 のドキュメントを読みましたが、ニーズを満たすための関数の作成方法が完全にはわかりません。さらに悪いことに、私はまだエンタープライズ版を試してみていないので、構文が正しくないことをお詫びします。

たとえば、itemsテーブルと、そのアイテムのデータを含むitemdataテーブルがある場合、itemid mod 30のような関数に基づいてデータを分割することにより、itemdataテーブルをパーティション分割するとします。これにより、アイテム1がパーティション1に配置され、アイテム2がパーティション2に配置されます。これをパーティション関数、スキーム、テーブル宣言で実行できるかどうか、または計算列を作成して使用する必要があるかどうかはわかりません。バリュー句?また、パフォーマンスが向上するかどうかわかりませんか?

これは私たちがこれを実装できると私が思う方法です:

CREATE PARTITION FUNCTION SplittingItemIds_PFunc(decimal(18,0)) AS
RANGE LEFT FOR VALUES
(0,1,2,3, ... ,29)

CREATE PARTITION SCHEME SplittingItemIds_Scheme 
AS PARTITION SplittingItemIds_PFunc
ALL TO ([PRIMARY]);

CREATE TABLE ItemData  
(
    Id decimal(18,0),
    ItemId decimal(18,0),
    ...
)
ON PartitionSplittingItemIds_Scheme(ItemId % 30)

CREATE INDEX ItemData_ItemId_Idx ON ItemData(ItemId);

これは大丈夫ですか?私が読んだものから、インデックスは自動的に分割されます-それは正しいですか?

4
Adam Butler

Dbaは、テーブルパーティションではなく horizo​​ntal partitioning について話しているようですが、テーブルAで文字a goで始まるすべての顧客など、テーブルAで始まるすべての顧客など、問題のあるテーブルを壊します。これは状況によっては役立つ場合があり、SQLサーバーのどのエディションでも実行できますが、すでに述べた同じ問題の多く、つまりI/Oがあります。

2
SqlACID

基になるIO /ディスクが不透明な場合、ソフトウェアはこれを修正できません。

  • パーティションを追加すると、30スレッドは生成されません
  • すべてのパーティションが同じボリューム上にある場合、スループットが低下します

私は私たちが持っていたのと同じようなシステムで働いてきました

  • ステージングDB
  • ステージングでの簡単なリカバリ
  • 時間外に実行される遅延削除(新規または更新された実行はINSERTなど)
  • 各実行には、このステータスを追跡するためのヘッダー行があります
  • クライアントの準備ができたら実際のDBにフラッシュする

また、

  • メインテーブルのFKとその他の調整を削除
  • ステージングDBを別のボリュームに配置します。
8
gbn