web-dev-qa-db-ja.com

Sch-Sロックを保持するための選択クエリを回避する方法

Selectクエリの実行時にSch-Sロックを回避するオプションを探しています。

私は自分のアプリケーションだけでなく、他の人が作成したアプリケーションによって制御されるデータベースを持っています。テーブルの1つに数百万の行があります。ダーティリードなどの問題はありませんが、クエリからのSch-Sロックのために待機する必要がある他のアプリケーションのインデックス作成または変更クエリをロックするための選択クエリはありません。

クエリを呼び出す前に分離レベルのスナップショットを設定しようとしましたが、それでも、Sch-Sロックを取得するWITH NOLOCKオプションに違いはありませんでした。

Sch-Sやロックを取得せずにテーブルで選択を実行するオプションを探しています。スナップショット/ビューまたは一時コピーをすばやく取得できる場合(何百万行ものデータがあるので機能しますか?)いかなる種類のロックもまったく取得せずにテーブルの。

4
AKS

Sch-Sロックはスキーマ安定性ロックです。これは、テーブルの構造が変更されないようにするためのものです。これには、列の追加/削除などが含まれます。NOLOCKヒントと分離レベルは、テーブル自体の構造ではなく、テーブル内のデータのロックとバージョン管理に影響します。

オンラインのインデックス操作でさえ、Sch-SおよびSch-Mロックを簡単に取得する必要があります。インデックス付けまたはスキーマ変更クエリでは、これを回避することはできません。

5
StrayCatDBA

StrayCatDBAとその回答に同意します。

スキーマ安定性ロックは、SQL Serverに必要な要素の1つです。ダーティリード(またはコミットされていないリードで発生する問題)を吸収することはできますが、クエリの途中で基礎となるスキーマが変更されることによる影響を吸収することはできません。実際、SQLもそれを処理できませんでした。つまり、それはあなたが取り除くことができないロックです。

しかし、私はここに根底にあるより深い疑問があるように感じます。なぜ私はこれを言うのですか? 20年前からSQL Serverを使用していて、SCH-SまたはSCH-Mロックを伴うロックに時々イライラしてきましたが、「ああ!これらの厄介なスキーマの安定性を取り除くことができれば、またはスキーマ変更ロック、すべて解決されます!!」

それぞれがSCH-Sロックを保持している2つの選択は、クエリに悪影響を与えません。更新はSCH-Sロックを保持しているため、selectをブロックしません。読み取りコミット(デフォルト)分離レベルにあり、テーブルまたはページレベルで必要なロックがロックと互換性がない場合、ブロックされます。たとえば、更新のために。

だから私はあなたに質問を振り返って、あなたがSCH-Sロックによって焼き付けられるためにあなたが何をしているのか尋ねます。 SCH-Sロックは通常、他の何かがテーブルの切り捨て、テーブルの変更、列の変更などを試みていない限り、またはインデックスの再構築操作中に問題を引き起こしません。

したがって、(1)本番ワークロード中にテーブルに対して発生するDMLを分析する必要がある状況が発生する可能性があります。 (2)または、別のロックタイプが実際の問題である状況。 (3)あるいは、このロックタイプに沿ったブロックが何らかの意味で意味をなす何かを本当に実行している状況。

それらのために、私はおそらくパスの1つから始めるでしょう:

  1. ライブから読み取ろうとしているテーブルでDMLをライブで行う理由を理解し、それをやめるか、他の場所でそれらの読み取りをオフラインにするより良いプロセスを考え出します。
  2. これは私が疑っているものです。ブロッキングSQLを試してみてください(SP_Whoisactiveを使用してブロックをキャッチしてください-ブロッキングsession_idは何ですか?何をしているのですか?それを見て、それが本当に問題かどうかを確認してください)。真のブロッキング原因に対処します。
  3. これが本当に予想される動作である場合。テーブルのコピーにデータを取得するには、他の方法を整理する必要があります。ここにはたくさんのアプローチがあります。 2つのテーブル(ETL、読み取り可能なAGセカンダリ、レプリケーションなど)にストリーミングします。ただし、これらの手法にはすべてSCH-Sロックが含まれます。つまり、SCH-Sが保持するロックをブロックする必要がある唯一の操作は、SCH-Mロックになります。したがって、これが発生する唯一の方法は、テーブルのデータをクエリしている間に誰かがテーブルのSTRUCTUREを変更することです。

私の推測では、あなたは本当にガチョウを追いかけているのですが、問題は#2です。

更新-あなたの質問をもう一度読んで、A。)問題がなく、予防的/心配しているだけの良好な状況であるか、またはB.)アプリケーションがインデックスまたはテーブルの非常に高い頻度で実行していると確信しています。製造日の途中での変更。私はあなたがここで大丈夫だと確信しています。そして、すべてのデータをコピーしてSCH-Sロックを通知するだけの答えは、実際にはうまく適合しません。そのデータをコピーして最新に保ち、SCH-Sロックを生成することで、パフォーマンスの問題が増える可能性があります。そこ。

本当の答えは、SCH-SロックによってブロックされるSCH-Mロックを引き起こしているベンダーのアプリの操作を確認することです。おそらく、企業の場合、おそらく頻度が低いなどの場合、オンラインインデックスの再構築を確認します。

4
Mike Walsh

別のパーティションで他のTRUNCATEクエリが機能を継続できるように、sch-sロックを取得しないようにパーティションテーブルでSELECTクエリを必要とする同じ状況に遭遇しました。驚いたことに、私がselectクエリを小さなバッチで実行すると、sch-sロックは99.99%に減少しますであることがわかりました。 Truncateが完了するまでに数ミリ秒しか必要なかったので、これは私の状況に最適でした。しかし、パーティション全体で完全なSELECTを使用すると、sch-sはselectの全期間にわたって保持されたため、TRUNCATEはselectの全期間にわたってブロックされました。

1
Anup Shah