我有这个查询
DECLARE @Company VARCHAR(20) = 'ABC'
DECLARE @Train INT = 1
SELECT L.*
FROM vemd_episodes_firstnet_currentPatients L
INNER JOIN vemd_episodes E ON E.Company = L.Company
AND E.cpid = L.cpid
AND E.dDate = L.dDate
WHERE L.Company = @Company
AND ((census_datetime NOT IN (SELECT MAX(census_datetime) FROM vemd_episodes_firstnet_currentPatients ) AND @Train = 1)
OR (census_datetime IN (SELECT MAX(census_datetime) FROM vemd_episodes_firstnet_currentPatients ) AND @Train = 0))
这需要永远的时间。
1分钟后,它仅检索400条记录,并且仍在运行。
此查询应获取的记录总数约为500,000条记录。
但是当我对查询中的参数进行硬编码
SELECT L.*
FROM vemd_episodes_firstnet_currentPatients L
INNER JOIN vemd_episodes E ON E.Company = L.Company
AND E.cpid = L.cpid
AND E.dDate = L.dDate
WHERE L.Company = 'ABC'
AND ((census_datetime NOT IN (SELECT MAX(census_datetime) FROM vemd_episodes_firstnet_currentPatients ) AND 1 = 1)
OR (census_datetime IN (SELECT MAX(census_datetime) FROM vemd_episodes_firstnet_currentPatients ) AND 1 = 0))
它非常快,可以在16秒内检索500k记录。
为什么在where
子句中使用参数会导致此问题?以及如何解决?
编辑:
我不能一直运行到最后
所以我选择前1000名并制定了执行计划
答案 0 :(得分:4)
您可以尝试使用重新编译选项OPTION (RECOMPILE)
查询
对于参数化查询,SQL有时会选择错误的执行计划并坚持使用它。
DECLARE @Company VARCHAR(20) = 'ABC'
DECLARE @Train INT = 1
SELECT L.*
FROM vemd_episodes_firstnet_currentPatients L
INNER JOIN vemd_episodes E ON E.Company = L.Company
AND E.cpid = L.cpid
AND E.dDate = L.dDate
WHERE L.Company = @Company
AND ((census_datetime NOT IN (SELECT MAX(census_datetime) FROM vemd_episodes_firstnet_currentPatients ) AND @Train = 1)
OR (census_datetime IN (SELECT MAX(census_datetime) FROM vemd_episodes_firstnet_currentPatients ) AND @Train = 0))
OPTION (RECOMPILE)
答案 1 :(得分:2)
尝试使用窗口功能:
SELECT L.*
FROM (SELECT L.*,
MAX(census_datetime) OVER () as max_census_datetime
FROM vemd_episodes_firstnet_currentPatients L
) L JOIN
vemd_episodes E
ON E.Company = L.Company AND
E.cpid = L.cpid AND
E.dDate = L.dDate
WHERE L.Company = @Company AND
((census_datetime <> max_census_datetime AND @Train = 1) OR
(census_datetime = max_census_datetime AND @Train = 0)
);
优化器应该发现使用更简单的where
子句可以更容易地生成适当的执行计划。