patternMinor
Slow Parallel SQL Server query, almost instant in serial
Viewed 0 times
sqlalmostqueryslowserialparallelinstantserver
Problem
I have a SQL Server query as follows (obfuscated):
We have just upgraded our (test) server to SQL Server 2016 SP2 from SQL Server 2014 SP3.
The performance of the query above appears to have fallen off a cliff as a result of this.
When the server was on SQL Server 2014, the database compatibility level was 120. Now it is on SQL Server 2016, the compatibility level for the database is still 120, however I have tried the query in 110,120 and 130, all with the same result.
When I run
The wait info suggests that the query has been waiting on
This to me suggests some issue with paralellism so I ran the query with the hint
UPDATE [TABLE1]
SET [COLUMN1] = CAST('N' AS CHAR(1))
FROM [TABLE1]
WHERE (COLUMN1 = '2' AND COLUMN2 IN('VAL1', 'VAL2', 'VAL3')) OR
(COLUMN1 <> 'N' AND (
SELECT COUNT(*)
FROM TABLE2 wle
JOIN TABLE3 wl
ON wl.COLUMN3 = wle.COLUMN3
WHERE TABLE1.COLUMN4 = wle.COLUMN4 AND
(wl.COLUMN5 = '1' OR wl.COLUMN6 = '1') AND
wle.COLUMN7 = (
SELECT MIN(alias.COLUMN7)
FROM TABLE2 AS alias
WHERE TABLE1.COLUMN4 = alias.COLUMN4
)
) > 0
)We have just upgraded our (test) server to SQL Server 2016 SP2 from SQL Server 2014 SP3.
The performance of the query above appears to have fallen off a cliff as a result of this.
When the server was on SQL Server 2014, the database compatibility level was 120. Now it is on SQL Server 2016, the compatibility level for the database is still 120, however I have tried the query in 110,120 and 130, all with the same result.
When I run
sp_whoisactive, I can see the wait_info is (48847425ms)CXCONSUMER suggesting that the query has been waiting for CXCONSUMER for the last 48847425ms (814 minutes) The query has currently been running for 13:34:07.587.The wait info suggests that the query has been waiting on
CXCONSUMER for the majority, if not all of its execution time.This to me suggests some issue with paralellism so I ran the query with the hint
Solution
Is there a way to fix this without changing the code?
Create the following index to eliminate the eager index spools:
With that in place, you should get a plan similar to:
The other problems described in the question will almost certainly disappear once you give the optimizer good indexes.
It is possible (though unlikely) your query suffers from an undetected intra-query parallelism deadlock (IQPD). A very detailed investigation would be needed to confirm that. The vast majority of IQPDs are detected and can then be resolved by spilling exchange buffers to tempdb. An undetected IQPD will result in the query being stuck forever.
Create the following index to eliminate the eager index spools:
-- Give this index a better name
CREATE INDEX i ON dbo.TABLE2 (COLUMN4, COLUMN7) INCLUDE (COLUMN3);With that in place, you should get a plan similar to:
The other problems described in the question will almost certainly disappear once you give the optimizer good indexes.
It is possible (though unlikely) your query suffers from an undetected intra-query parallelism deadlock (IQPD). A very detailed investigation would be needed to confirm that. The vast majority of IQPDs are detected and can then be resolved by spilling exchange buffers to tempdb. An undetected IQPD will result in the query being stuck forever.
Code Snippets
-- Give this index a better name
CREATE INDEX i ON dbo.TABLE2 (COLUMN4, COLUMN7) INCLUDE (COLUMN3);Context
StackExchange Database Administrators Q#286451, answer score: 5
Revisions (0)
No revisions yet.