Jeff Moden (7/16/2014)
Igor Micev (7/14/2014)
--Extend this index to make it coverable for the query:
CREATE UNIQUE NONCLUSTERED INDEX [UIX_did_uid_sid] ON [Dim].[UserDevice]
(
[DeviceID] ASC,
[UserID] ASC,
[SubscriberID] ASC
)
INCLUDE(
Locale,[LastUsedDate]
)
--Create this index
CREATE UNIQUE NONCLUSTERED INDEX [UIX_NCSTransaction_IDs] ON [Ext].[NCSTransaction]
(
[SubscriberID],[UserID],[DeviceID]
)
INCLUDE ([Locale],location,[TransactionStartDateTime])
If the "select" part of the merge statement takes 4 minutes, then you'd better replace that code with a temp table and put the second index on the temp table.
I think there is a chance to improve it a lot. So it's your turn
Since the ROW_NUMBER partitioning in the query is...
row_number() over(partition by [SubscriberID],[UserID],[DeviceID] order by transactionstartdatetime desc) as rn
... you might erg out a bit more performance if you made that second index include the transactionstartdatetime desc as a part of the key rather than a part of the INCLUDE.
Hi Jeff,
I'm not sure about your proposal.
Example:
CREATE NONCLUSTERED INDEX [Index1] ON [dbo].[FactProductInventory]
([ProductKey] ASC,
[DateKey] ASC)
CREATE NONCLUSTERED INDEX [Index2] ON [dbo].[FactProductInventory]
([ProductKey] ASC)
INCLUDE([DateKey])
DBCC DROPCLEANBUFFERS
set statistics io on
SELECT t.ProductKey,t.DateKey
FROM DBO.FactProductInventory t
set statistics io off
/* Index2 used automatically by SQL Server
(776286 row(s) affected)
Table 'FactProductInventory'. Scan count 1, logical reads 1352, physical reads 3, read-ahead reads 1362, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
*/
DBCC DROPCLEANBUFFERS
set statistics io on
SELECT t.ProductKey,t.DateKey
FROM DBO.FactProductInventory t with (index (Index1))
set statistics io off
/* Forcing Index1
(776286 row(s) affected)
Table 'FactProductInventory'. Scan count 1, logical reads 1352, physical reads 3, read-ahead reads 1362, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
*/
Both columns are INT type. The query optimizer chose to use the index which is narrower (Index2). I think it would be still more firm for the real scenario from above.
Igor Micev,My blog: www.igormicev.com