下面是一段类似于我正在使用的代码。
DECLARE
@UserParam = NULL --optional paramater
SELECT
rtrim(item) [aKey]
INTO
#aKeyTable
FROM
myDB.dbo.fnSplit(@UserParam,',')
SELECT
/* Lots of columns, not important to the question */
FROM
myDB.dbo.tableB b
JOIN myDB.dbo.tableC c ON c.cKey = b.bKEY
AND (c.columnA IN
(
SELECT
aKey
FROM
#aKeyTable
)
OR @UserParam IS NULL)
我的问题是:如何删除子查询以提高性能。
要求:
- @UserParam是可选的
- @UserParam可以有多个逗号分隔的参数
- @UserParam必须匹配表 C 中的列 A 或为 NULL
- 使用 WHERE 子句也不是一种选择,它也会对性能产生太大影响
我正在使用 SQL Server 2014
更新:我的整个查询很长,平均运行大约需要 15-20 秒,具体取决于参数,但根据执行计划,此子查询使用了 89% 的性能。在此之前,我在 WHERE 子句中将其用于性能,性能相当,有时更慢。
谢谢
如果没有查询计划,很难确定; 也就是说,也许在 aKey 列上创建一个索引?
您是否考虑过使用 TVP?它们最适合此目的。另请阅读Erland Sommarskog了解更多详情。
将不同的案例合并到一个执行计划中是有问题的。当@UserParam
为空时,情况与不空时完全不同。您应该为每个案例制定执行计划。您可以诱导一个IF
并进行两个查询。有关更多参数,您最终会得到动态 sql,因为否则组合的指数增长是无法管理的。
优化程序应将表变量的行数估计为 1,从而导致索引查找。如果参数的选择性良好,这应该有效。