【发布时间】:2013-06-21 07:08:52
【问题描述】:
我的生产环境中有一个查询需要很长时间才能执行。我没有写这个查询,但我必须找到一种方法让它更快,因为它目前正在导致一个很大的性能问题。我需要用 Left Join 替换 NOT IN 但不知道如何重写它。现在好像在关注
SELECT TOP 1 IT.ITEMID
FROM (SELECT CAST(ITEMID AS NUMERIC) + 1 ITEMID
FROM Items
WHERE ISNUMERIC(ITEMID) = 1
AND CAST(ITEMID AS NUMERIC) >= 50000) IT
WHERE IT.ITEMID NOT IN (SELECT CAST(ITEMID AS NUMERIC) ITEMID
FROM Items
WHERE ISNUMERIC(ITEMID) = 1)
ORDER BY IT.ITEMID
请建议我应该如何使用 Left Join 重写它以获得更好的性能。非常感谢任何帮助/指导。
【问题讨论】:
-
如果您没有可供查询使用的索引,
NOT IN到LEFT JOIN / IS NULL(或到NOT EXISTS)将无济于事。 -
A LEFT JOIN / IS NULL 通常比 NOT IN/NOT EXISTS 慢。正如@ypercube 所说,这是一个索引问题,CAST 和谓词上的功能无助于使索引使用无效。
-
另外,
ISNUMERIC(ITEMID) = 1 AND CAST(ITEMID AS NUMERIC) >= 50000不会做你希望它做的事情,因为 a) 无法保证评估谓词的顺序,b) 仅仅因为ISNUMERIC返回 1,所以不保证您可以将值转换为NUMERIC。 -
例如,尝试以下两个选择语句:
select ISNUMERIC('0d5'),然后是select CAST('0d5' as NUMERIC)。 -
所以看起来这个查询应该找到
ITEMID序列中的最小间隙,即>50000?您使用的是哪个版本的 SQL Server?为什么需要这个?
标签: sql-server performance tsql sql-server-2008-r2