存储过程运行缓慢,但过去表现良好

Rob*_*n16 3 performance sql-server-2014 query-performance

http://pastebin.com/index.php?e=1我知道您可能在职业生涯中多次或至少听说过一次这个问题,但这已经成为我们环境中巨大的性能问题。

数据库大小:压缩后1 TB表大小:800 GB,超过十亿条记录

应用程序通常查询存储过程,当他们运行报告时,它通常调用存储过程并最终查询巨大的视图(它有接近 900 列,视图中的一个表是上面提到的 800GB 表)。

环境概述:

SQL 2014 企业版,Always On 无表分区(计划今年实施) Windows 2012 标准内存:512,490 GB 分配给 SQL Server CPU:16 核

问题:当报表运行时,它调用存储过程,存储过程最终根据用户选择的动态参数生成动态 SQL。因此,这里的问题是每次执行都会在计划缓存中生成新计划。

每当出现问题时,我们都会通过添加/删除一些过滤器作为临时解决方法来调整内部代码,但我们在这里寻找的是找到解决此问题的最终解决方案。

我们做过的事情:

  1. 我们已经根据该大表中每个索引的样本百分比修改的行设置了一个不同的自定义更新统计作业。
  2. 由于时间的原因,我们不会在这个巨大的表上重建索引,但我们会根据页数进行重组。由于数据倾斜,根据 SQLSkills 的建议,在问题表(大表)上创建过滤统计(我们正在与 SQL Skills 团队并行工作)

要做的事情:

表分区 - 我正在考虑创建过滤索引。如果您遇到任何这些问题,请告诉我您的想法或建议。

Rob*_*ley 8

我很好奇计划的样子,即使性能很差。希望您可以调整这些计划,然后确保动态 SQL 为这些条件生成正确的查询。

不过,您可能想要寻找一些东西:

确保您的视图设置为简化不需要的连接。观看http://bit.ly/Simplification以了解如何操作。

如果使用特定的计划形状,请考虑使用 QO 可以使用的其他谓词。在关于反向谓词的部分观看http://bit.ly/Sargability。但是,还要考虑诸如寻找之类的事情,year(thedate) = @y以便您可以将其更改为thedate >= datefromparts(@y,1,1) and thedate < datefromparts(@y+1,1,1)(或者,如果您有一个索引计算列)。

附加的 IS NOT NULL 谓词可用于帮助简化某些连接。

检查您是否在可能的情况下避免使用 OR 和 IN,或者至少考虑一下影响是什么。在某些情况下,您可能希望将someval in (1,2,4)(在一个运算符内进行三次搜索)更改为someval >= 1 and someval <= 4 and someval != 3(在某个范围内进行一次搜索),但要注意这对复合索引的影响。阅读http://sqlperformance.com/2016/06/sql-plan/whats-actually-going-on-with-that-seek了解更多信息。

当不使用过滤器时,请确保完全忽略它而不是使用包罗万象的谓词。您可能会发现您要求它检查您真正不关心的值。希望你已经这样做了。