SQL Server選択カウントREAD_COMMITTED_SNAPSHOT QUESTION


8

特定のテーブルでselect count(*)を実行すると、多くのデッドロックが発生しているようです。私はすでにすべての必要なパラメーターを変更し、それらを行のみのロックにしています。

また、READ_COMMITTED_SNAPSHOT分離を使用するようにデータベースを変更しました。

ただし、select count(*)where column =?テーブル上でデッドロックまたはテーブル上のロックをトリガーします。

select count(*)は中間行にのみアクセスする必要があることは正しいのでしょうか?しかし、それはそのようには見えず、依然としてデッドロックが発生しています。適切な索引付けはおそらく役立つでしょう。

問題は、SQL Server 2008 R2は、read_committed_snapshotがonに設定されている場合でも、select count(*)中にテーブルに共有ロックを設定しますか?

ありがとう


(リクエストの時点で)正確な数が必要ですか、それともおおよその数で大丈夫ですか?
Jon Seigel 2013年

実際には、共有ロックが設定されているかどうかを知る必要があるだけです。デッドロックの問題を調査しようとしています。ありがとう
grassbl8d 2013年

私の要点は、カウントの取得方法を変更することを検討できれば、それがデッドロックの問題を解決する方法になるかもしれないということでした。しかし、もう一度質問を読んだので、WHERE句を使用する必要がある場合、私が考えている方法はとにかく機能しません。
Jon Seigel 2013年

where句がフィルター選択されたインデックスと一致する場合、テーブルのサブセットのメタデータテーブルから概数を取得できます。
アーロンバートランド

回答:


2

READ_COMMITTED_SNAPSHOTに注意してください。これをオンに設定すると、多くの微妙なバグが発生する可能性があります。

また、READ_COMMITTED_SNAPSHOTはデフォルトの分離レベルであり、何かによってオーバーライドされる場合があります。DBCC USEROPTIONSを実行して、選択が実行される実際の分離レベルを決定します。

選択する直前に、トランザクションの分離レベルのスナップショットを明示的に設定します。そうすることで、selectがデッドロックを受け入れないことが確実になり、READ_COMMITTED_SNAPSHOTのように他のコードを壊すことがなくなります。


0

スナップショットアイソレーションによるロックは変更されません。変更点は、ページがあなたの下で変更されるときに、それらのページがtempdbデータベースにコピーされ、通常のデータベースからではなくtempdbデータベースからそれらを読み取ることができることです。(はい、これは起こっていることの簡略化されたバージョンです。)

適切なインデックスが設定されていないため、クラスター化インデックススキャン(またはヒープの場合はテーブルスキャン)を実行しているとのことですが、これは、tempdbデータベースに移動する大量のデータになる可能性があります。このクエリが複数回実行されるものである場合は、テーブルにインデックスを追加することをお勧めします。

クエリはどの分離レベルを使用していますか?


私はread_commited_snapshot分離レベルを使用しています。デフォルトでread_committedを使用しているので、これをオンにしました。選択カウント中にロックが設定されているかどうかだけに興味があります。おかげで、私はすでにインデックスを配置しました
grassbl8d

はい、まだロックがかかっています。sys.dm_tran_locksをクエリして、取得されているロックを確認できます。あるウィンドウでクエリを実行し、別のウィンドウでsys.dm_tran_locksをクエリして、どのロックが取得されているかを確認します。テーブルロックにエスカレートしていて、ヒントを使用してページまたは行レベルのロックを強制する必要がある場合があります。
mrdenny、2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.