SQL Server:引擎会从视图中执行不需要的东西吗?

Posted

技术标签:

【中文标题】SQL Server:引擎会从视图中执行不需要的东西吗?【英文标题】:SQL Server: Will the engine execute things from a view that are not needed? 【发布时间】:2010-02-03 21:45:48 【问题描述】:

如果我有一个生成多个列的视图:

CREATE VIEW dbo.foo AS
SELECT 
    id,
    SUM(SELECT [...] ) AS c1,
    STDEV(SELECT [...] ) AS c2,
    AVG(SELECT [...] ) AS c3,
    MIN(SELECT [...] ) AS c4,
    MAX(SELECT [...] ) AS c5,
    SUM(SELECT [...] ) AS c6,
    [...]
    COUNT(SELECT [...] ) AS cN,
FROM Table
GROUP BY id

但我最终只要求其中一个计算值:

SELECT id, c382
FROM foo
WHERE id = 42

SQL Server 会计算所有列值,然后忽略它们吗?

根据我的经验,答案似乎是“是”。一个查询:

SELECT id, c382
FROM foo
WHERE id = 42

会比我想象的要慢。如果我打破了抽象,复制我想要的代码:

SELECT id, c382
FROM (
      SELECT 
       id,
       MAX(SELECT [...] ) AS c382
   FROM Table
   GROUP BY id
) AS MiniView
WHERE id = 42

查询运行得更好。

或者也许它在更真实的世界构造中开始分崩离析:

SELECT bar.*, foo.384
FROM bar
    INNER JOIN foo
    ON bar.Bing = foo.id
WHERE bar.Reticulated = 'splines'

我疯了,还是 SQL Server (2000) 疯了?

【问题讨论】:

“跑得更好”是什么意思?你看过执行计划吗?它应该清楚地说明这一点。 在今天的特定示例中,我正在模拟带有视图的维度表。 @Mehrdad,不需要执行计划就知道视图会比 select 语句运行得更糟。 【参考方案1】:

这是它在 SQL Server 2000 中通常的工作方式。这在 SQL Server 2005 及更高版本中也基本得到修复。

【讨论】:

简单,简洁,我认为是真的。我没有测试它是否在 2005 年修复,但我相信你是对的。 +1 并被接受。【参考方案2】:

你问题的最后一部分我没看懂,但第一部分是真实的陈述,用观点总结了问题。

虽然视图可以帮助使数据库更易于理解,但很少会因为此类问题而使其性能更高。

将视图视为存储选择语句的宏的最佳方式。视图被引用的地方将被视图的内容完全替换。

大多数时候,使用存储过程 IMO 可以做得更好。

【讨论】:

无法加入存储过程 不,你写一个新的存储过程,只做你想做的事。或者将 proc 中的值放入临时表并加入该表。从性能的角度来看,在数据库中广泛使用视图通常是一个坏主意。就我个人而言,我很少使用视图。我宁愿在数据库中看到大量的触发器,也不愿看到大量的视图。 我将不得不再次检查它,但我认为如果您将视图的连接替换为派生表的连接:sql server 将不会执行不需要的东西。 关于视图内容被完全替换的部分是错误的。 SQL 2005 做了一些谓词推送(进入视图),而 SQL 2008 做得更好。【参考方案3】:

是的,视图将计算您的所有聚合列,仅使用您指定的列。

不幸的是,这就是观点。

但是,您可以避免在视图中创建这么多不会使用的列吗?

【讨论】:

...或为这些列的所有可能组合创建一个视图,并将一个与您需要的列一起使用。 (笑) @astander:该视图用于计算附加信息,可在报告和分析期间使用。 @Hogan:对于所有 1 Cab 被使用不会导致将被使用,或者可能的良好性能......没有人说要创建 1..n 列。在需要时创建所需内容,然后在需要时进行性能调整。 @astander:你在那边中风什么的?需要我叫医生什么的吗?【参考方案4】:

您可以创建一个物化视图(一个被索引并提高性能的视图,但请注意,您不能在调用视图的视图上执行此操作(如果您认为现在性能很差,请等到您尝试) .

现在是关于在数据库中广泛使用视图的警示故事。我们有一些应用程序开发人员选择使用视图,他们从不直接访问仅表视图。设计时间很棒,一切看起来都很棒,而且看起来很容易维护。让网站上线并加载大量客户数据,而不是他们测试的小数据集,超时从第一天开始。随着时间的推移,随着客户需求的变化,他们改变了越来越多的东西。每次他们都是通过一个视图来做的。最终,称为视图的视图称为视图,性能(已经很糟糕)直线下降。最后,他们创建了一个视图,其中包含如此多的视图,以至于它遇到了可以在查询中引用的表数量的限制(现在请注意,这些表都是相同的表,只是在调用的视图中都被多次引用彼此)。客户对似乎没有人能够解决的糟糕性能感到愤怒(毕竟这将涉及从头开始重新设计应用程序中的每个查询)并将业务转移到其他地方。这是该公司最大的客户——对于做设计的开发人员来说并不是那么好。

【讨论】:

上次我检查时,无法在物化视图中进行聚合。有什么变化吗?

以上是关于SQL Server:引擎会从视图中执行不需要的东西吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server 2008 中执行视图时出现“超时已过期”错误

SQL Server视图

在 SQL 中检查 IF 条件,即使它不匹配

01基础架构,一条SQL查询语句是如何执行的?

SQL Server中的执行引擎入门

mysql的一条sql是如何执行的