SQL Server 2008 のデッドロック グラフを使用して、SQL サーバーのデッドロックの問題を診断しました。
問題は私のインデックスに関係しています。2 つのクエリがあります。ベース テーブルの 2 つの異なる日付に従ってデータを取得する多数の結合とサブクエリを含む長期実行レポートと、そのベース テーブルの同じ日付を更新するクイック更新クエリです。2 つのインデックスがあり、レポートは両方に共有 KEY ロックを必要としますが、更新クエリはそれらの両方に排他的 KEY ロックを必要とし、どういうわけか各クエリはキーの 1 つしか取得できないため、どちらも続行できません。
これを修正するにはどうすればよいですか?
ここに私の状況に関するすべての詳細があります:
私のベーステーブルは次のようになります。
CREATE TABLE job_tb{
job_id int IDENTITY(1,1),
createDate datetime NULL,
upDate datetime NULL,
dataField1 nchar(1),
dataField2 nchar(2),
--etc...
}
私のインデックスは次のようになります。
CREATE NONCLUSTERED INDEX idx_createDate ON job_tb(
createDate DESC
)
INCLUDE(dataField1, dataField2)
CREATE NONCLUSTERED INDEX idx_upDate ON job_tb(
upDate DESC
)
INCLUDE(dataField1, dataField2)
最後に、私の更新は次のようになります。
BEGIN TRANSACTION;
UPDATE job_tb
SET
dataField1 = @data
upDate = @upDate
WHERE
job_id = @job_id
COMMIT TRANSACTION;
また、このレポートはあらゆる種類の統計を日付別にカウントしているため、ここには含めません。idx_createDate と idx_upDate は、そのレポートで頻繁に使用されているため、dataField1 を「カバー」または含めるように意図的に設計しました。
レポートは、インデックスの 1 つで共有ロックを取得し、サブクエリにヒットして、2 番目のインデックスでロックを要求していると思います。一方、更新クエリは、upDate と含まれる dataField1 の両方を更新するために、両方のインデックスを排他的にロックする必要があります。
皆さんはどう思いますか?
編集: 要求された XML デッドロック グラフは次のとおりです。
<deadlock-list> <deadlock>
<victim-list>
<victimProcess id="processcf65288"/>
</victim-list>
<process-list>
<process id="processcf65288" taskpriority="0" logused="0" waitresource="KEY: 6:72057597970874368 (eee1799e706c)" waittime="122" ownerId="421742704" transactionname="SELECT" lasttranstarted="2012-08-03T05:37:21.257" XDES="0x8611e8800" lockMode="S" schedulerid="50" kpid="8560" status="suspended" spid="70" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2012-08-03T05:37:21.257" lastbatchcompleted="2012-08-03T05:37:21.257" clientapp="Internet Information Services" hostname="xxx" hostpid="11964" loginname="xxx" isolationlevel="read committed (2)" xactid="421742704" currentdb="6" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="" line="28" stmtstart="1276" stmtend="4826" sqlhandle="0x03000600311ac36c65a31701a1a000000100000000000000">
</frame>
<frame procname="" line="1" sqlhandle="0x01000600f61bee3600932ae3090000000000000000000000">
</frame>
</executionStack>
<inputbuf> exec MonthlyReport @id = 41
</inputbuf>
</process>
<process id="processd2b6bc8" taskpriority="0" logused="1908" waitresource="KEY: 6:72057597970939904 (8e8117a49479)" waittime="2242" ownerId="421742551" transactionname="user_transaction" lasttranstarted="2012-08-03T05:37:20.447" XDES="0x7e84ad0a0" lockMode="X" schedulerid="63" kpid="12700" status="suspended" spid="89" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2012-08-03T05:37:20.443" lastbatchcompleted="2012-08-03T05:37:20.443" clientapp="Internet Information Services" hostname="xxx" hostpid="11964" loginname="xxx" isolationlevel="read committed (2)" xactid="421742551" currentdb="6" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056">
<executionStack>
<frame procname="" line="47" stmtstart="2342" stmtend="2640" sqlhandle="0x03000600e7dd9c717cbbb900ec9f00000100000000000000">
</frame>
<frame procname="" line="1" sqlhandle="0x01000600311d7a152032f9be040000000000000000000000">
</frame>
</executionStack>
<inputbuf> exec UpdateJob @dataField1 = 'C', @upDate = '8/3/2012 5:37:20 AM', @job_id = 1542687
</inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057597970874368" dbid="6" objectname="" indexname="" id="lock612859900" mode="X" associatedObjectId="72057597970874368">
<owner-list>
<owner id="processd2b6bc8" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="processcf65288" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057597970939904" dbid="6" objectname="" indexname="" id="lock612a15300" mode="S" associatedObjectId="72057597970939904">
<owner-list>
<owner id="processcf65288" mode="S"/>
</owner-list>
<waiter-list>
<waiter id="processd2b6bc8" mode="X" requestType="wait"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock> /deadlock-list>