联接中的子查询会降低性能,从而寻找更好的替代方案



下面是一段类似于我正在使用的代码。

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,从而导致索引查找。如果参数的选择性良好,这应该有效。

最新更新