SQL Serverで、クエリヒントを使用するとロックにどのような影響が出るのかを調べてみました。
結論
標準クエリの場合、ISを取得するので、DDL文とXロック(SELECTだと、XLOCKクエリヒントを使ったクエリ)と競合する。UPDLOCKとは競合しない。
UPDLOCKは、キーにUを取得するので、DDL文と同一キーへのUとXと競合する。ページにIUを取得するので、ページへのUとXと競合する。キーへのUはトランザクション終了時まで保持される。
詳細は、ロックの互換性参照
調査方法
今回は単純なテーブルとクエリでの調査です。
4列あるテーブルで、100000行のデータを格納して、Where無しのクエリで処理をしています。
テーブル例
クエリ例
SELECT [Uid]
,[AddTime]
,[EnemyId]
,[StrongType]
FROM [dev_next_dev].[dbo].[AAA]
クエリヒント無し
データベースにSロックを取得・
テーブルにISロックを取得。
PageにISロックを取得しますね。(検証中、まれにSの時もあり)
UPDLOCK
データベースにSロック
テーブルにIXロック
PAGEにIUロック
KEYにUロックを取得します。Keyは全レコード(Top1000なので1000行)のロックを保持します。
これは、トランザクションが終了するまで保持されていて、トランザクションが終了すると、KEYのUロックとPAGEのIUロック、テーブルのIXロックが解除されます。
NOLOCK
データベースにSロックを取得します。
テーブルにSCH-Sロックを取得します。
SCH-Cロックは、DDL文発行時に取得されるSCH-Mロックとのみ競合します。
TABLOCK
データベースにSロック
テーブルに大量のSロック
XLOCK
データベースにSロック
テーブルにISロック
テーブルにIXロック
ページにIXロック
キーごとにXロック