これがこの質問をするのに多かれ少なかれ適切な場所であるかどうかはわかりません。元々 Stack Overflow で提起されていました。
SQL Server 2008では、テーブルV
とA
のビューB
があり、次のようになります。
create view V as
select * from A
union all
select * from B
V
から読み取ると、クエリはベーステーブルで意図的な共有ロックを取得しますが、ビューで意図的な共有ロックも取得します。オブジェクト自体。
ISテーブルのロックが必要な理由は明らかであり、ビューのISロックが原因で、いいですね.
クエリプランには、ビューの記述は含まれていません。これは完全にコンパイルされており、この場合の結果の計画は、2つのベーステーブルの行を単純に連結したものです。実際、クエリプランXMLでのビューの唯一の言及は、ステートメントテキストです。
テーブルに2番目のビューU
を追加した場合、V
からの読み取りによってU
がロックされることはありません。これは、エンジンがA
およびB
のすべてのビューでISロックを取得するだけであることを除外します。
データベースエンジンはどのようにしてビューをロックすることを知っていますか?
後者の場合、ストレージエンジンがビューをロックするために知っているメカニズムの詳細は、内部的にはかなり適切であると考えることができます。ただし、これがユーザーに表示されるという事実は、どこかに文書化されていることを期待しています。
良い質問。コンパイルと最適化プロセスの早い段階でビュー定義がクエリテキストveryに展開されることは事実ですが、あらゆる種類の情報がキャッシュされて追跡されます直接見えない計画など計画の調査で「興味深い」と見なされた統計。これらの統計が変更された場合に予想される再コンパイルが行われるようにします。これは、選択された最終的な計画の形状が変更された統計を直接利用しなかった場合でも当てはまります。より良い計画が利用できる可能性があるため、再コンパイルする必要があります。
同様に、ユーザーは、ビューを「使用」すると、そのビューの定義を変更しようとする同時試行がすべてブロックされるはずであると合理的に期待します。実際のコンパイルまたは最適化が行われる前に実装がビューテキストを展開しても、これは当てはまります。そのためには、ビューのobject_id
は、キャッシュされたプランの一部であり、プランが実行されるたびに、互換性の高いIntent-Sharedロックが使用されます。このロックを保持することにより、別のセッションがそのオブジェクトのSch-M(スキーマ変更)を取得し、論理的に参照している間(ビューが拡張されていても)、ビューを変更することを防ぎます。当然のことながら、ビューが参照するオブジェクトのロックでは不十分です。
この種のことを文書化すべきかどうかという質問に。何年にもわたるBooks Onlineの形は、何かを文書化することは、変更する前に非推奨のサイクルを経る必要があることを示唆しています。 いつでも '、この種の内部実装の詳細が正式なドキュメントになる可能性は低いようです。
エンジンまたはオプティマイザ関連のあらゆるものの究極のソースであるConor Cunninghamから:
コンパイル時に状況を追跡して、実行時にチェックします。この目的のために実行時に物事を解析することはありません。
注:あるリリースから別のリリースへの移行の内部は保証されていません。これは公式にサポートされている表面領域の下にあります。
私の考えでは、実行プランのバイナリバージョン(XMLを介して読み取りおよび公開されるものではなく、バイナリバージョンのサブセットにすぎません)には、元のクエリで参照されるビューへのポインターが含まれている必要があります。テキスト(これはSO質問で暗示されていました。)それは明らかにクエリテキストを毎回解析することではありません。Conorは上記と同じくらい意味しますが、どこについての詳細を明らかにしないように注意してくださいまたはこれがどのように保存されるか、これはリリースごとに、またはサービスパックや累積的な更新によってさえも変更される可能性があるためです。おそらく彼はまた、どんな探偵の仕事も奨励したくありません。:-)