I've been trying to optimise a data loading process. This is on Sqlserver 2016 (13.0.5850.14 - latest SP&CU). I've switched to change tracking for internal database changes and set tablocks on all my inserts. As change tracking recommends I've enabled snapshot isolation.
I'm now getting self-deadlocks. Originally I was getting some of the traditional Intra-Query Parallel Thread Deadlocks, so I created some cache tables as standard user tables with indexes and pre-populated them to simplify the plans significantly. Now I am getting a different kind of self-deadlock. These only have Page Locks in the TempDb (not an exchangeEvent in sight) which makes me think that something else is going on. It is now a pretty simple query left joining to a bunch of tables to lookup Keys and applying a where in clause on changetable(changes, ...) to only get those changed rows.
It doesn't deadlock if I either remove the where clause on changetable(changes, ...) (so my query is no longer honouring the change tracking) or if I don't run in a "set transaction isolation level snapshot" transaction. But change tracking explicitly says it is needed. I know I could set DOP to 1 but it does make a massive difference to the execution time.
I'm considering forgetting changetable and going back to having an indexed timestamp column for change tracking.
Interested in any other ideas?
here is the graph
<deadlock>
<victim-list>
<victimProcess id="processe3486d0ca8" />
</victim-list>
<process-list>
<process id="processe3486d0ca8" taskpriority="0" logused="20000" waittime="4255" schedulerid="2" kpid="11556" status="suspended" spid="86" sbid="0" ecid="13" priority="0" trancount="0" lastbatchstarted="2020-12-23T13:52:13.520" lastbatchcompleted="2020-12-23T13:52:13.380" lastattention="1900-01-01T00:00:00.380" clientapp="Microsoft SQL Server Data Tools, T-SQL Editor" hostname="BV002571" hostpid="15328" isolationlevel="snapshot (5)" xactid="510106180" currentdb="17" currentdbname="ValueRetailDW_41975" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200">
<executionStack>
<frame procname="ValueRetailDW_41975.star.LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS" line="72" stmtstart="7052" stmtend="8260" sqlhandle="0x030011003de9c87a648ddd009aac000001000000000000000000000000000000000000000000000000000000">
select
Transaction_id, TransactionDateKey, BarcodeNumber, CurrencyKey, VisitRecordKey, MarketingActivityKey, GroupBookingKey, BookingTypeKey, MarketingPartnerKey, Time, VillageKey, BrandKey, LeaseKey, CustomerKey, LocalisationKey, OfferKey, GeographyKey, eVIPTier, BarcodeMetadataSource, GrossBrandSalesTracked, TaxAmount, _AuditKey, _LoadTimestamp, _RecordSource
into #toload -- must insert into a temp table (not variable) to get parallel capability of the complex query
from [map].[DI_BIExport_TrackedSales_DS_TO_LOAD_FactTrackedSales] (@LastAnchor)
option (recompile </frame>
<frame procname="adhoc" line="1" stmtend="134" sqlhandle="0x01001100d905560c90db0fcae700000000000000000000000000000000000000000000000000000000000000">
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS </frame>
</executionStack>
<inputbuf>
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS] -- normal
</inputbuf>
</process>
<process id="processe348241848" taskpriority="0" logused="14148276" waitresource="PAGE: 2:3:27824 " waittime="10657" ownerId="510106180" transactionname="user_transaction" lasttranstarted="2020-12-23T13:52:13.520" XDES="0xe5f02d3ba0" lockMode="S" schedulerid="8" kpid="16044" status="suspended" spid="86" sbid="0" ecid="11" priority="0" trancount="0" lastbatchstarted="2020-12-23T13:52:13.520" lastbatchcompleted="2020-12-23T13:52:13.380" lastattention="1900-01-01T00:00:00.380" clientapp="Microsoft SQL Server Data Tools, T-SQL Editor" hostname="BV002571" hostpid="15328" isolationlevel="snapshot (5)" xactid="510106180" currentdb="17" currentdbname="ValueRetailDW_41975" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200">
<executionStack>
<frame procname="ValueRetailDW_41975.star.LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS" line="72" stmtstart="7052" stmtend="8260" sqlhandle="0x030011003de9c87a648ddd009aac000001000000000000000000000000000000000000000000000000000000">
select
Transaction_id, TransactionDateKey, BarcodeNumber, CurrencyKey, VisitRecordKey, MarketingActivityKey, GroupBookingKey, BookingTypeKey, MarketingPartnerKey, Time, VillageKey, BrandKey, LeaseKey, CustomerKey, LocalisationKey, OfferKey, GeographyKey, eVIPTier, BarcodeMetadataSource, GrossBrandSalesTracked, TaxAmount, _AuditKey, _LoadTimestamp, _RecordSource
into #toload -- must insert into a temp table (not variable) to get parallel capability of the complex query
from [map].[DI_BIExport_TrackedSales_DS_TO_LOAD_FactTrackedSales] (@LastAnchor)
option (recompile </frame>
<frame procname="adhoc" line="1" stmtend="134" sqlhandle="0x01001100d905560c90db0fcae700000000000000000000000000000000000000000000000000000000000000">
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS </frame>
</executionStack>
<inputbuf>
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS] -- normal
</inputbuf>
</process>
<process id="processe34820b848" taskpriority="0" logused="14148276" waitresource="PAGE: 2:3:27824 " waittime="10657" ownerId="510106180" transactionname="user_transaction" lasttranstarted="2020-12-23T13:52:13.520" XDES="0xe5fdd5dcb0" lockMode="S" schedulerid="1" kpid="9460" status="suspended" spid="86" sbid="0" ecid="16" priority="0" trancount="0" lastbatchstarted="2020-12-23T13:52:13.520" lastbatchcompleted="2020-12-23T13:52:13.380" lastattention="1900-01-01T00:00:00.380" clientapp="Microsoft SQL Server Data Tools, T-SQL Editor" hostname="BV002571" hostpid="15328" isolationlevel="snapshot (5)" xactid="510106180" currentdb="17" currentdbname="ValueRetailDW_41975" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200">
<executionStack>
<frame procname="ValueRetailDW_41975.star.LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS" line="72" stmtstart="7052" stmtend="8260" sqlhandle="0x030011003de9c87a648ddd009aac000001000000000000000000000000000000000000000000000000000000">
select
Transaction_id, TransactionDateKey, BarcodeNumber, CurrencyKey, VisitRecordKey, MarketingActivityKey, GroupBookingKey, BookingTypeKey, MarketingPartnerKey, Time, VillageKey, BrandKey, LeaseKey, CustomerKey, LocalisationKey, OfferKey, GeographyKey, eVIPTier, BarcodeMetadataSource, GrossBrandSalesTracked, TaxAmount, _AuditKey, _LoadTimestamp, _RecordSource
into #toload -- must insert into a temp table (not variable) to get parallel capability of the complex query
from [map].[DI_BIExport_TrackedSales_DS_TO_LOAD_FactTrackedSales] (@LastAnchor)
option (recompile </frame>
<frame procname="adhoc" line="1" stmtend="134" sqlhandle="0x01001100d905560c90db0fcae700000000000000000000000000000000000000000000000000000000000000">
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS </frame>
</executionStack>
<inputbuf>
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS] -- normal
</inputbuf>
</process>
<process id="processe3486d3468" taskpriority="0" logused="14148276" waitresource="PAGE: 2:3:27824 " waittime="10657" ownerId="510106180" transactionname="user_transaction" lasttranstarted="2020-12-23T13:52:13.520" XDES="0x106a5a07ce0" lockMode="S" schedulerid="7" kpid="9868" status="suspended" spid="86" sbid="0" ecid="12" priority="0" trancount="0" lastbatchstarted="2020-12-23T13:52:13.520" lastbatchcompleted="2020-12-23T13:52:13.380" lastattention="1900-01-01T00:00:00.380" clientapp="Microsoft SQL Server Data Tools, T-SQL Editor" hostname="BV002571" hostpid="15328" isolationlevel="snapshot (5)" xactid="510106180" currentdb="17" currentdbname="ValueRetailDW_41975" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200">
<executionStack>
<frame procname="ValueRetailDW_41975.star.LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS" line="72" stmtstart="7052" stmtend="8260" sqlhandle="0x030011003de9c87a648ddd009aac000001000000000000000000000000000000000000000000000000000000">
select
Transaction_id, TransactionDateKey, BarcodeNumber, CurrencyKey, VisitRecordKey, MarketingActivityKey, GroupBookingKey, BookingTypeKey, MarketingPartnerKey, Time, VillageKey, BrandKey, LeaseKey, CustomerKey, LocalisationKey, OfferKey, GeographyKey, eVIPTier, BarcodeMetadataSource, GrossBrandSalesTracked, TaxAmount, _AuditKey, _LoadTimestamp, _RecordSource
into #toload -- must insert into a temp table (not variable) to get parallel capability of the complex query
from [map].[DI_BIExport_TrackedSales_DS_TO_LOAD_FactTrackedSales] (@LastAnchor)
option (recompile </frame>
<frame procname="adhoc" line="1" stmtend="134" sqlhandle="0x01001100d905560c90db0fcae700000000000000000000000000000000000000000000000000000000000000">
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS </frame>
</executionStack>
<inputbuf>
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS] -- normal
</inputbuf>
</process>
<process id="processe6d5137848" taskpriority="0" logused="14148276" waitresource="PAGE: 2:3:27824 " waittime="10657" ownerId="510106180" transactionname="user_transaction" lasttranstarted="2020-12-23T13:52:13.520" XDES="0xe95493e960" lockMode="S" schedulerid="6" kpid="19216" status="suspended" spid="86" sbid="0" ecid="10" priority="0" trancount="0" lastbatchstarted="2020-12-23T13:52:13.520" lastbatchcompleted="2020-12-23T13:52:13.380" lastattention="1900-01-01T00:00:00.380" clientapp="Microsoft SQL Server Data Tools, T-SQL Editor" hostname="BV002571" hostpid="15328" isolationlevel="snapshot (5)" xactid="510106180" currentdb="17" currentdbname="ValueRetailDW_41975" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200">
<executionStack>
<frame procname="ValueRetailDW_41975.star.LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS" line="72" stmtstart="7052" stmtend="8260" sqlhandle="0x030011003de9c87a648ddd009aac000001000000000000000000000000000000000000000000000000000000">
select
Transaction_id, TransactionDateKey, BarcodeNumber, CurrencyKey, VisitRecordKey, MarketingActivityKey, GroupBookingKey, BookingTypeKey, MarketingPartnerKey, Time, VillageKey, BrandKey, LeaseKey, CustomerKey, LocalisationKey, OfferKey, GeographyKey, eVIPTier, BarcodeMetadataSource, GrossBrandSalesTracked, TaxAmount, _AuditKey, _LoadTimestamp, _RecordSource
into #toload -- must insert into a temp table (not variable) to get parallel capability of the complex query
from [map].[DI_BIExport_TrackedSales_DS_TO_LOAD_FactTrackedSales] (@LastAnchor)
option (recompile </frame>
<frame procname="adhoc" line="1" stmtend="134" sqlhandle="0x01001100d905560c90db0fcae700000000000000000000000000000000000000000000000000000000000000">
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS </frame>
</executionStack>
<inputbuf>
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS] -- normal
</inputbuf>
</process>
<process id="processe348cbb088" taskpriority="0" logused="14148276" waitresource="PAGE: 2:3:27824 " waittime="10657" ownerId="510106180" transactionname="user_transaction" lasttranstarted="2020-12-23T13:52:13.520" XDES="0xec5ec16960" lockMode="S" schedulerid="3" kpid="13816" status="suspended" spid="86" sbid="0" ecid="14" priority="0" trancount="0" lastbatchstarted="2020-12-23T13:52:13.520" lastbatchcompleted="2020-12-23T13:52:13.380" lastattention="1900-01-01T00:00:00.380" clientapp="Microsoft SQL Server Data Tools, T-SQL Editor" hostname="BV002571" hostpid="15328" isolationlevel="snapshot (5)" xactid="510106180" currentdb="17" currentdbname="ValueRetailDW_41975" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200">
<executionStack>
<frame procname="ValueRetailDW_41975.star.LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS" line="72" stmtstart="7052" stmtend="8260" sqlhandle="0x030011003de9c87a648ddd009aac000001000000000000000000000000000000000000000000000000000000">
select
Transaction_id, TransactionDateKey, BarcodeNumber, CurrencyKey, VisitRecordKey, MarketingActivityKey, GroupBookingKey, BookingTypeKey, MarketingPartnerKey, Time, VillageKey, BrandKey, LeaseKey, CustomerKey, LocalisationKey, OfferKey, GeographyKey, eVIPTier, BarcodeMetadataSource, GrossBrandSalesTracked, TaxAmount, _AuditKey, _LoadTimestamp, _RecordSource
into #toload -- must insert into a temp table (not variable) to get parallel capability of the complex query
from [map].[DI_BIExport_TrackedSales_DS_TO_LOAD_FactTrackedSales] (@LastAnchor)
option (recompile </frame>
<frame procname="adhoc" line="1" stmtend="134" sqlhandle="0x01001100d905560c90db0fcae700000000000000000000000000000000000000000000000000000000000000">
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS </frame>
</executionStack>
<inputbuf>
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS] -- normal
</inputbuf>
</process>
<process id="processe97dff0ca8" taskpriority="0" logused="14148276" waitresource="PAGE: 2:3:27824 " waittime="10657" ownerId="510106180" transactionname="user_transaction" lasttranstarted="2020-12-23T13:52:13.520" XDES="0x10691260df0" lockMode="S" schedulerid="5" kpid="11736" status="suspended" spid="86" sbid="0" ecid="15" priority="0" trancount="0" lastbatchstarted="2020-12-23T13:52:13.520" lastbatchcompleted="2020-12-23T13:52:13.380" lastattention="1900-01-01T00:00:00.380" clientapp="Microsoft SQL Server Data Tools, T-SQL Editor" hostname="BV002571" hostpid="15328" isolationlevel="snapshot (5)" xactid="510106180" currentdb="17" currentdbname="ValueRetailDW_41975" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200">
<executionStack>
<frame procname="ValueRetailDW_41975.star.LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS" line="72" stmtstart="7052" stmtend="8260" sqlhandle="0x030011003de9c87a648ddd009aac000001000000000000000000000000000000000000000000000000000000">
select
Transaction_id, TransactionDateKey, BarcodeNumber, CurrencyKey, VisitRecordKey, MarketingActivityKey, GroupBookingKey, BookingTypeKey, MarketingPartnerKey, Time, VillageKey, BrandKey, LeaseKey, CustomerKey, LocalisationKey, OfferKey, GeographyKey, eVIPTier, BarcodeMetadataSource, GrossBrandSalesTracked, TaxAmount, _AuditKey, _LoadTimestamp, _RecordSource
into #toload -- must insert into a temp table (not variable) to get parallel capability of the complex query
from [map].[DI_BIExport_TrackedSales_DS_TO_LOAD_FactTrackedSales] (@LastAnchor)
option (recompile </frame>
<frame procname="adhoc" line="1" stmtend="134" sqlhandle="0x01001100d905560c90db0fcae700000000000000000000000000000000000000000000000000000000000000">
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS </frame>
</executionStack>
<inputbuf>
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS] -- normal
</inputbuf>
</process>
<process id="process106d192c108" taskpriority="0" logused="14148276" waitresource="PAGE: 2:3:27824 " waittime="10657" ownerId="510106180" transactionname="user_transaction" lasttranstarted="2020-12-23T13:52:13.520" XDES="0xef0a3d9c00" lockMode="S" schedulerid="4" kpid="17492" status="suspended" spid="86" sbid="0" ecid="9" priority="0" trancount="0" lastbatchstarted="2020-12-23T13:52:13.520" lastbatchcompleted="2020-12-23T13:52:13.380" lastattention="1900-01-01T00:00:00.380" clientapp="Microsoft SQL Server Data Tools, T-SQL Editor" hostname="BV002571" hostpid="15328" isolationlevel="snapshot (5)" xactid="510106180" currentdb="17" currentdbname="ValueRetailDW_41975" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200">
<executionStack>
<frame procname="ValueRetailDW_41975.star.LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS" line="72" stmtstart="7052" stmtend="8260" sqlhandle="0x030011003de9c87a648ddd009aac000001000000000000000000000000000000000000000000000000000000">
select
Transaction_id, TransactionDateKey, BarcodeNumber, CurrencyKey, VisitRecordKey, MarketingActivityKey, GroupBookingKey, BookingTypeKey, MarketingPartnerKey, Time, VillageKey, BrandKey, LeaseKey, CustomerKey, LocalisationKey, OfferKey, GeographyKey, eVIPTier, BarcodeMetadataSource, GrossBrandSalesTracked, TaxAmount, _AuditKey, _LoadTimestamp, _RecordSource
into #toload -- must insert into a temp table (not variable) to get parallel capability of the complex query
from [map].[DI_BIExport_TrackedSales_DS_TO_LOAD_FactTrackedSales] (@LastAnchor)
option (recompile </frame>
<frame procname="adhoc" line="1" stmtend="134" sqlhandle="0x01001100d905560c90db0fcae700000000000000000000000000000000000000000000000000000000000000">
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS </frame>
</executionStack>
<inputbuf>
exec [star].[LOAD_FactTrackedSales_FROM_DI_BIExport_TrackedSales_DS] -- normal
</inputbuf>
</process>
</process-list>
<resource-list>
<SyncPoint id="SyncPointef0598ed00" logicalOperatorType="Left Outer Join" physicalOperatorType="Hash Match" WaitType="HTMEMO" nodeId="8" synchronizingAt="ReadyForHashTableMemoColumn" ownerActivity="NotYetArrived" waiterActivity="Arrived">
<owner-list>
<owner id="process106d192c108" />
<owner id="processe6d5137848" />
<owner id="processe348241848" />
<owner id="processe34820b848" />
<owner id="processe3486d3468" />
<owner id="processe348cbb088" />
<owner id="processe97dff0ca8" />
</owner-list>
<waiter-list>
<waiter id="processe3486d0ca8" />
</waiter-list>
</SyncPoint>
<pagelock fileid="3" pageid="27824" dbid="2" subresource="FULL" id="lockee0a16d800" mode="X">
<owner-list>
<owner id="processe97dff0ca8" mode="S" requestType="wait" />
</owner-list>
<waiter-list>
<waiter id="processe348241848" mode="S" requestType="wait" />
</waiter-list>
</pagelock>
<pagelock fileid="3" pageid="27824" dbid="2" subresource="FULL" id="lockee0a16d800" mode="X">
<owner-list>
<owner id="processe97dff0ca8" mode="S" requestType="wait" />
</owner-list>
<waiter-list>
<waiter id="processe34820b848" mode="S" requestType="wait" />
</waiter-list>
</pagelock>
<pagelock fileid="3" pageid="27824" dbid="2" subresource="FULL" id="lockee0a16d800" mode="X">
<owner-list>
<owner id="processe97dff0ca8" mode="S" requestType="wait" />
</owner-list>
<waiter-list>
<waiter id="processe3486d3468" mode="S" requestType="wait" />
</waiter-list>
</pagelock>
<pagelock fileid="3" pageid="27824" dbid="2" subresource="FULL" id="lockee0a16d800" mode="X">
<owner-list>
<owner id="processe97dff0ca8" mode="S" requestType="wait" />
</owner-list>
<waiter-list>
<waiter id="processe6d5137848" mode="S" requestType="wait" />
</waiter-list>
</pagelock>
<pagelock fileid="3" pageid="27824" dbid="2" subresource="FULL" id="lockee0a16d800" mode="X">
<owner-list>
<owner id="processe97dff0ca8" mode="S" requestType="wait" />
</owner-list>
<waiter-list>
<waiter id="processe348cbb088" mode="S" requestType="wait" />
</waiter-list>
</pagelock>
<pagelock fileid="3" pageid="27824" dbid="2" subresource="FULL" id="lockee0a16d800" mode="X">
<owner-list>
<owner id="processe3486d0ca8" mode="X" />
</owner-list>
<waiter-list>
<waiter id="processe97dff0ca8" mode="S" requestType="wait" />
</waiter-list>
</pagelock>
<pagelock fileid="3" pageid="27824" dbid="2" subresource="FULL" id="lockee0a16d800" mode="X">
<owner-list>
<owner id="processe97dff0ca8" mode="S" requestType="wait" />
</owner-list>
<waiter-list>
<waiter id="process106d192c108" mode="S" requestType="wait" />
</waiter-list>
</pagelock>
</resource-list>
</deadlock>
SyncPoint
in the deadlock XML. Can you provide the query plan for the insert query?