视图中的列数是否会影响性能?

4
我有一个视图从一个表中提取了大约200列,没有使用联接。使用该视图的过程仅使用其中大约10列。视图中是否存在额外的190列会对使用视图的性能产生显著影响?
编辑:根据原问题者的评论进行澄清,他的过程中的查询仅使用了200个中的10个列。问题是,因为底层视图包含200列,这是否仍会导致性能下降,或者优化器知道仅使用10列并忽略视图的其他190列?
谢谢,
克里斯

我不清楚你所说的procs是指存储过程还是客户端程序。 - Lieven Keersmaekers
它们是存储过程,由asp.net应用程序调用的服务器上的程序。 - Chris Burgess
你应该对使用视图和不使用视图进行分析,但我不会太担心。基本上,当你从存储过程中调用视图时,SQL Server会展开它。我相信优化器足够聪明,能够找出真正需要的列。 - Lieven Keersmaekers
我对该视图运行了两个SELECT查询,一个选择了10列,另一个选择了所有列,并在Profiler中进行了观察。它们都有相同数量的读取,但是选择较少列的查询的持续时间和CPU使用率都要小得多。 - Chris Burgess
4个回答

3

1
一个视图中有190个多余的列,但未被引用,这是件坏事吗? - Chris Burgess

1
首先,如果你的视图限制了使用WHERE子句,你可能会遭受性能惩罚,至少由于无法在10个列上使用良好的索引与视图自己使用的索引冲突而导致。

如果视图仅限制了列但没有WHERE子句,则不确定-请参见下面的详细信息:

根据这篇文章,我推断你会遭受惩罚,因为视图不一定是使用你的10个列编译的,你可能会继承糟糕的查询计划。

测试非常容易:

  1. 运行查询

    select * from myView where someNonIndexedColumn = someValue

    (确保where子句中的列不在原始表的任何索引中)。

  2. 使用查询计划运行上述查询,并确保它执行表扫描。

  3. 现在,选择一些在原始表上的索引中的列,例如确保对它们的查询应使用覆盖索引。例如,在索引I1中的C1和C2。

  4. 运行

    select C1, C2 from myTable where C1=x and C2=Y

    并打开查询计划,确保它使用"I1"索引作为覆盖索引。

  5. 运行

    select C1, C2 from myView where C1=x and C2=Y

    并打开查询计划,检查它是否执行表扫描或使用I1作为覆盖索引。

我怀疑它会执行一次表扫描,那么你的答案是“对性能来说,190列是一个坏事情”- 基本上,Ryan Fonnett链接文章中的所有负面影响都适用于你的观点。

如果(不太可能)它在#5中使用覆盖索引,则thew拥有190列的事实就不相关了。


0

当然,这完全取决于情况。它总会产生影响。但是,如果我们谈论的是在与数据库运行在同一服务器上的应用程序,并且每个列都包含一些字节,则影响不应该太大。

另一方面,如果我们谈论的是通过网络运行客户端来访问数据库,并提取190个额外的列,例如(string*255),那么如果您的网络管理员能够抓住您,那么您就有大麻烦了。

无论哪种情况,查询如此多的不必要列并不是很优雅。为什么不调整查询,只查询所需的列呢?我假设您使用的是“select * from ...”,这会产生另一个问题:当有人更改视图(添加列或删除列)时,您的程序将被阻塞。


0

不要问我们,这是你应该自己测试的东西,因为答案可能高度依赖于你的数据库和视图结构以及查询结构和设备组合。尝试从视图中选择四列并与直接从涉及的表中选择它们进行比较,你将知道是否存在可测量的性能差异。如果你有多个嵌套的视图,我怀疑你会发现有可测量的差异,但如果只有一个视图,则可能不是很重要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接