当使用以下代码时:
SELECT * INTO #StoreIdsPermision FROM (SELECT StoreId FROM dbo.FN_Inv_GetListOfStoreIdCheckPermission(15,3019)) StoreIdsPermision;
SELECT distinct
Id,
StoreName,
......,
......,
from INV_Transactions
inner join ....
left outer join ....
WHERE StoreId in (select Id from #StoreIdsPermision)
执行时间为 4 分钟。
当在“WHERE IN”语句中使用相同的逗号语法代码时,执行时间为3秒,为什么?以及如何解决这个问题?
SELECT distinct
Id,
StoreName,
......,
......,
from INV_Transactions
inner join ....
left outer join ....
WHERE StoreId in (4,7,9,15,22,........)
注意:以下语句的执行时间不到1秒,并且#StoreIdsPermision仅约140行
SELECT * INTO #StoreIdsPermision FROM (SELECT StoreId FROM dbo.FN_Inv_GetListOfStoreIdCheckPermission(15,3019)) StoreIdsPermision;
第 1 部分的实际执行计划
第 2 部分的实际执行计划
使用逗号语法时的实际执行计划
更新1:
来自“Eponyme Web”建议二号的非常好的建议,当在第一个查询中添加 SET FORCEPLAN ON 并在最后一个查询中添加 SET FORCEPLAN OFF 时,执行时间正常,会发生什么情况?
更新2:
我将所有内连接替换为左外连接,并且在没有 FORCEPLAN ON 的情况下也能正常工作
最佳答案
您已确认第一个查询的第一部分不会导致问题?
SELECT *
INTO #StoreIdsPermision
FROM
(SELECT StoreId
FROM dbo.FN_Inv_GetListOfStoreIdCheckPermission(15, 3019)) StoreIdsPermision;
如果上述代码不是性能问题的根源,您可以向 #StoreIdsPermision 临时表添加索引
CREATE INDEX sip1 ON #StoreIdsPermision (StoreId);
我会尝试另外两件事(始终将创建的索引保留在临时表上)
1 - 用这个替换你的 where 子句
WHERE EXISTS (SELECT 1 from #StoreIdsPermision SIP WHERE INV_Transactions.StoreId = SIP.StoreId)
2 - 在第二个查询开始时启用强制计划,并在最后关闭强制计划。 99.9% 的情况下,优化器都会正确或至少足够正确,但有时却不会。在您的情况下,我预计这两种方法的性能不会有如此大的差异。
关于sql - T-SQL Select where "IN"非常糟糕 性能影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54978531/