5

我最近才意识到您现在可以在 SQL Server 中索引您的视图(请参阅http://technet.microsoft.com/en-us/library/cc917715.aspx)。我现在正试图弄清楚何时从针对索引视图的查询与在缓存了执行路径的存储过程中的相同查询中获得更好的性能?

举个例子:

SELECT colA, colB, sum(colC), sum(colD), colE
FROM myTable
WHERE colFDate < '9/30/2011'
GROUP BY colA, colB, colE

每次运行时日期都会有所不同,因此如果这是一个视图,我不会将其包含WHERE在视图中,而是将其作为我对视图的选择的一部分。如果它是一个存储过程,则日期将是一个参数。请注意,表中有大约 300,000 行。其中 200,000 人将满足带有日期的 where 条款。10,000 将在分组后返回。

如果这是一个索引视图,我是否应该期望从中获得比有机会缓存​​执行路径的存储过程更好的性能?还是proc会更快?或者差异可以忽略不计?我知道我们可以说“两者都试一试”,但是有太多因素可能会使结果产生错误的偏差,导致我得出错误的结论,所以我想听听更多背后的理论以及预期的结果是什么.

谢谢!

4

1 回答 1

8

索引视图可以看作是一个普通的表——它是一个物化行集合。

所以问题真的归结为“正常”查询是否比存储过程快。

如果您查看 SQL Server 执行任何查询(存储过程调用或临时 SQL 语句)所执行的步骤,您会发现(大致)这些步骤:

  1. 从语法上检查查询
  2. 如果没问题 - 它检查计划缓存以查看它是否已经有该查询的执行计划
  3. 如果有执行计划 - 该计划被(重新)使用并执行查询
  4. 如果还没有计划,则确定执行计划
  5. 该计划存储到计划缓存中以供以后重用
  6. 查询被执行

关键是:ad-hoc SQL 和存储过程在处理上没有什么不同

如果一个 ad-hoc SQL 查询正确地使用了参数——无论如何,为了防止 SQL 注入攻击——它的性能特征没有什么不同,而且绝对不会比执行存储过程差。

存储过程还有其他好处(例如,无需授予用户直接表访问权限),但就性能而言,使用适当参数化的 ad-hoc SQL 查询与使用存储过程一样有效。

在非参数化查询上使用存储过程更好,主要有两个原因:

  • 由于每个非参数化查询都是对 SQL Server 的一个新的、不同的查询,因此对于每个查询,它必须经历确定执行计划的所有步骤(因此浪费时间 - 并且还浪费计划缓存空间,因为存储执行计划进入计划缓存最终并没有真​​正的帮助,因为该特定查询可能不会再次执行)

  • 非参数化查询存在 SQL 注入攻击的风险,应不惜一切代价避免

现在当然,如果您的索引视图可以显着减少行数(通过使用GROUP BY子句) - 那么索引视图当然会比您针对整个数据集运行存储过程时快得多。但这并不是因为采用了不同的方法——这只是规模问题——查询几十或几百行将比查询 200'000 或更多行更快——无论您以哪种方式查询。

于 2013-12-24T15:26:26.743 回答