インベントリレポートを生成するプロセスがあります。クライアント側では、プロセスは構成可能な数のワーカースレッドを分割して、多数(潜在的に数千、通常は数十)のうちの1つのストアに対応するレポートのデータのチャンクを構築します。各ワーカースレッドは、ストアドプロシージャを実行するWebサービスを呼び出します。
各チャンクを処理するデータベースプロセスは、一連のデータを#Temporaryテーブルに収集します。各処理チャンクの最後に、データはtempdbの永続テーブルに書き込まれます。最後に、プロセスの最後に、クライアント側の1つのスレッドが永続的なtempdbテーブルからすべてのデータを要求します。
このレポートを実行するユーザーが多いほど、速度は遅くなります。データベース内のアクティビティを分析しました。ある時点で、プロセスのある時点で35の個別のリクエストがすべてブロックされているのがわかりました。これらのSPIDはすべて、リソースMETADATA_SEQUENCE_GENERATOR (00000010E13CA1A8)
で_LATCH_EX
_タイプの50ミリ秒の待機がありました。 1つのSPIDにこのリソースがあり、他のすべてのSPIDがブロックしています。この待機リソースについては、ウェブ検索で何も見つかりませんでした。
使用しているtempdbのテーブルにはIDENTITY(1,1)
列があります。これらのSPIDはIDENTITY列を待機していますか?ブロッキングを削減または排除するためにどのような方法を使用できますか?
サーバーはクラスターの一部です。サーバーは、64ビットのWindows 2008 R2 Enterpriseで64ビットのSQL Server 2012 Standard Edition SP1を実行しています。サーバーは64 GB RAM=および48プロセッサを備えていますが、データベースは標準エディションであるため、16のみを使用できます。
(このすべてのデータを保持するためにtempdbの永続テーブルを使用する設計にわくわくしないことに注意してください。これを変更することは、技術的および政治的な興味深い課題になるでしょうが、私は提案を受け入れます。)
2013年4月23日更新
マイクロソフトでサポートケースをオープンしました。詳細については、この質問を更新していきます。
2013年5月10日更新
SQL Serverのサポートエンジニアは、待機がIDENTITY列によって引き起こされたことに同意しました。 IDENTITYを削除すると、待機がなくなりました。 SQL 2008 R2では問題を再現できませんでした。 SQL 2012でのみ発生しました。
問題をID値の生成に分離できると仮定すると(その列をテストとして削除してみてください)、これがお勧めです。
IDENTITY
プロパティを削除します。したがって、ストアIDが3と4の場合、最終的には次のような最終的なID値になります。
3000000001
3000000002
3000000003
...
4000000001
4000000002
...
またはそれに似たもの。あなたはアイデアを得ます。
これにより、最終結果の一意性を維持しながら、IDENTITY
生成でシリアル化する必要がなくなります。
または、プロセスの動作に応じて、最終的に計算されたID値を#Temporaryテーブルに挿入します。次に、UNION ALL
sそれらを一緒にして、データをまったくコピーする必要をなくします。
(2019年2月更新)
これは古い投稿ですが、これが実際に発生した事実は実際に欠陥であるとマイクロソフトを納得させることができました。
更新:MS欠陥を確認し、バグ#12628722を割り当てました。
SQL Server 2005からSQL Server 2017にアップグレードした後、2018年11月のこの投稿を見て、同じように苦しみ始めました。一括挿入に10秒かかっていた330万行のテーブルが突然10を使用し始めましたIdentity
列を持つテーブルの分。
これには2つの問題があることがわかります。
4週間かかったが、休暇の直後にサンタから遅れたプレゼントが届いた-問題が実際に欠陥であることが確認された。
これが修正されるまで、いくつかの回避策があります。
Option (MaxDop 1)
を使用して、一括挿入をシリアル化されたプランに戻します。Select Cast(MyIdentityColumn As Integer) As MyIdentityColumn
)SELECT...INTO
の使用時にIDプロパティがコピーされなくなりますUpdate:MSが実装する修正は、これらの種類の挿入を返すことですSerialized
プランの使用に戻ります。これはSql Server 2017 CU14のために計画されています(他のバージョンのSql Serverに関するニュースはありません-ごめんなさい!)。実装されている場合、トレースフラグ9492は、サーバーレベルまたはviaDBCC TraceOn
のいずれかでオンにする必要があります。