多分支SQL查询运行缓慢

时间:2015-06-17 16:10:37

标签: sql sql-server performance

对于包含许多可选参数的报表和WHERE子句中的20-30个分支,我有一个大型SQL查询。问题是它运行速度很慢。执行时间从6秒到5分钟不等。如果我删除一个或两个条件,它在6秒内工作,但在所有条件下,它需要超过5分钟。问题不在于任何特定索引或条件,因为如果我从查询中删除任何一个条件,它会改进。连接中有大约20个表,输出中有大约100个字段。查询的问题区域如下所示:

        AND Abc_ID IN (SELECT * FROM fnSplit(@Abc_IDs, ','))
        AND Xyx_ID IN (SELECT * FROM fnSplit(@Xyz_Ids, ','))
        AND Aaa_ID IN (SELECT * FROM fnSplit(@Aaa_Ids, ','))
        AND Zzz_ID IN (SELECT * FROM fnSplit(@Zzz_Ids, ','))

其中fnSplit是一个udf。另请注意,如果我删除带有硬编码值(1,2,3,4,5)的fnsplit,它也会改进。但我的猜测是问题是与服务器内存或某些配置有关,而不是在WHERE中的特定子句中。正如我之前所说,WHERE子句中有20-30个分支,删除任何一个条件可以提高性能(很多)。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您可以尝试的初始事项/想法很少:

  1. 从执行计划中最左边的对象检查“提前终止的原因”。如果超时,那可能是(可怕的)糟糕计划的原因

  2. 测试是否用temp替换(SELECT * FROM fnSplit ..)。表可以帮助优化器更好地理解基数

  3. 查看“statistics io”,执行计划和计划缓存消耗最多I / O和CPU的内容,这可能有助于了解问题所在

  4. 将整个事物更改为动态SQL

  5. 包括执行计划,统计io和表&索引结构等进入进一步分析的问题

  6. 奖金创意:将您的拆分功能与DelimitedSplit8k进行比较,可能会更好。