hi all, I'm having a problem tuning this query. I have tried refactoring it a few different ways and none of them has help. The best I can get was to realign the nonclustered index and adding a query hint of forceseek. But this query gets called 110,202 times a day, with a logical read of 8,694,249,658. This is on a "good day."
I have also tried to compress the index but that helped i/o only a little bit. I think the problem is with the RIGHT join and can't seem to work around it.
SELECT [side].[Id] ,[base].[OrderId] ,[base].[Branch] ,[base].[ProductId] ,[base].[OrderLineNumber] ,[base].[OrderedQuantity] ,[base].[AllocatedQuantity] ,[base].[InvoicedQuantity] ,[base].[OrderedWeight] ,[base].[AllocatedWeight] ,[base].[UnitPrice] ,[base].[ExtendedPrice] ,[base].[PriceMethod] ,[base].[PriceMargin] ,[base].[LineStatus] ,[base].[LineJITStatus] ,[base].[BasePrice] ,[base].[AdagePriceNumberKey] ,[base].[OrderDate] ,[side].[sync_row_is_tombstone] ,[side].[local_update_peer_timestamp] AS sync_row_timestamp ,CASE WHEN ( [side].[update_scope_local_id] IS NULL OR [side].[update_scope_local_id] <> @sync_scope_local_id ) THEN COALESCE([side].[restore_timestamp], [side].[local_update_peer_timestamp]) ELSE [side].[scope_update_peer_timestamp] END AS sync_update_peer_timestamp ,CASE WHEN ( [side].[update_scope_local_id] IS NULL OR [side].[update_scope_local_id] <> @sync_scope_local_id ) THEN CASE WHEN ([side].[local_update_peer_key] > @sync_scope_restore_count) THEN @sync_scope_restore_count ELSE [side].[local_update_peer_key] END ELSE [side].[scope_update_peer_key] END AS sync_update_peer_key ,CASE WHEN ( [side].[create_scope_local_id] IS NULL OR [side].[create_scope_local_id] <> @sync_scope_local_id ) THEN [side].[local_create_peer_timestamp] ELSE [side].[scope_create_peer_timestamp] END AS sync_create_peer_timestamp ,CASE WHEN ( [side].[create_scope_local_id] IS NULL OR [side].[create_scope_local_id] <> @sync_scope_local_id ) THEN CASE WHEN ([side].[local_create_peer_key] > @sync_scope_restore_count) THEN @sync_scope_restore_count ELSE [side].[local_create_peer_key] END ELSE [side].[scope_create_peer_key] END AS sync_create_peer_key FROM [core].[OrderProduct] [base](forceseek) RIGHT JOIN [core].[OrderProduct_tracking] [side] ON [base].[Id] = [side].[Id] WHERE ( ( [side].[OrderId] IN ( SELECT [core].[Order].[Id] FROM [core].[Order] WHERE [core].[Order].[AccountId] IN ( SELECT [express].[UserAccount].[AccountId] FROM [express].[UserAccount] WHERE [express].[UserAccount].[UserId] = @userid ) ) ) OR ( [side].[sync_row_is_tombstone] = 1 AND ( [side].[update_scope_local_id] = @sync_scope_local_id OR [side].[update_scope_local_id] IS NULL ) AND [side].[OrderId] IS NULL ) ) AND ( [side].[update_scope_local_id] IS NULL OR [side].[update_scope_local_id] <> @sync_scope_local_id OR ( [side].[update_scope_local_id] = @sync_scope_local_id AND [side].[scope_update_peer_key] <> @sync_update_peer_key ) ) AND [side].[local_update_peer_timestamp] > @sync_min_timestamp core.OrderProduct table has 25,159,177 rows with the following index: clustered index on base.id core.OrderProduct_Tracking table has 25,181,838 rows with the following index: clustered index on side.id nonclustered index on side.orderid, side.sync_row_is_tombstone, side.update_scope_local_id, side.local_update_peer_timestamp, side.id Here's the execution plan: I know the forceseek caused the clustered index seek and cost 88% but w/o that, the query runs super slow! Nightly, I have the index either reorg or rebuild and update its statistics. This query alone sucks up huge amount of memory and the wait for it is over 108 hrs in a 24 hr time frame. if anyone can provide some guidance, that would be great! Thanks, |
- Edited by Red8Rain 17 hours 33 minutes ago