我最近才意识到您现在可以在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会更快吗?或者差异可以忽略不计?我知道我们可以说"只是尝试两种方式",但有太多因素可能会错误地偏向结果导致我得出错误的结论,所以我想听到更多关于它背后的理论以及预期的结果是什么.
谢谢!
一个索引视图可以看作像一个正常的表-这是一个物化行的集合.
所以问题实际上归结为"正常"查询是否比存储过程更快.
如果您查看SQL Server执行任何查询(存储过程调用或临时SQL语句)的步骤,您将(大致)找到这些步骤:
语法检查查询
如果没关系 - 它会检查计划缓存,看它是否已经有该查询的执行计划
如果有执行计划 - 该计划被(重新)使用并执行查询
如果还没有计划,则确定执行计划
该计划存储在计划缓存中以供以后重用
执行查询
关键是:ad-hoc SQL和存储过程没有区别.
如果ad-hoc SQL查询正确使用参数 - 无论如何应该防止SQL注入攻击 - 它的性能特征没有什么不同,并且绝对不会比执行存储过程更糟糕.
存储过程具有其他好处(例如,无需授予用户直接表访问权限),但就性能而言,使用正确参数化的即席SQL查询与使用存储过程一样高效.
对非参数化查询使用存储过程更好,主要有两个原因:
由于每个非参数化查询都是对SQL Server的一个新的不同查询,因此必须对每个查询执行确定执行计划的所有步骤(从而浪费时间 - 并且还浪费计划缓存空间,因为存储执行计划进入计划缓存最终并没有真正帮助,因为那个特定的查询可能不会再次执行)
非参数化查询存在SQL注入攻击的风险,应该不惜一切代价避免
当然,如果您是索引视图可以显着减少行数(通过使用GROUP BY
子句) - 那么当然,索引视图将比您对整个数据集运行存储过程时快得多.但这并不是因为采用了不同的方法 - 这只是一个规模问题 - 查询几十行或几百行将比查询200'000或更多行更快 - 无论您查询哪种方式.