SQL Server 2008:将 VIEW 与其他 VIEW 联接:预先计算而不求助于临时表

Posted

技术标签:

【中文标题】SQL Server 2008:将 VIEW 与其他 VIEW 联接:预先计算而不求助于临时表【英文标题】:SQL Server 2008: Join VIEW with other VIEW: precalculate without resorting to temp tables 【发布时间】:2010-10-11 18:09:35 【问题描述】:

为了在我的数据库中执行转换,我经常使用一组链式视图。在视图中将是公用表表达式。例如,我会有以下内容:

CREATE VIEW TransformationStep1 AS
    WITH Transformation1A AS (
        SELECT Field1, Field2, Field3, Bla(Field1) AS Calc FROM Table1
    ),
    Transformation1B AS (
        SELECT Field1, Field2, Field3, Calc FROM Transformation1A
    )
    SELECT * FROM Transformation1B

CREATE VIEW TransformationStep2 AS
    WITH Transformation2A AS (
        SELECT Field1, Calc FROM TransformationStep1
    ), ....

在 TransformationStep4 附近的某个地方,随着查询计划变得更加复杂,视图将变得更慢。这是预期的,可以的。

但是,当我想将 TransformationStep4 的一部分连接到自身时,查询将大大减慢,因为优化器试图找到返回源表并寻找某种索引的方式。通常这是可以的,但有时我只想存储我的临时结果并加入,因为(作为故事中的设计人员)我知道结果表会很小,加入会快得多反对它的“预取”。

有没有办法让我编写一个查询提示,它会影响查询计划,使子查询被预取然后加入反对?否则我将不得不求助于存储过程中的临时表,但如果可以的话,我想避免它。

感谢您的任何建议,以及当您认为我的设计很糟糕时:-)

【问题讨论】:

【参考方案1】:

视图是扩展的宏:没有缓存或预取预计算。

除非你有索引视图,你可以使用 NOEXPAND.. 但这些不会在普通视图上工作。

但是,您也可以使用内部 TOP/ORDER BY 来具体化视图:

SELECT
   *
FROM
   (SELECT TOP 2000000000 * FROm TransformationStep2 ORDER BY soemthing) V1
   JOIN
   (SELECT TOP... ) bar on foo.x = bar.x

视图没有什么神奇之处:它只是文本,没有记忆或持久性......

【讨论】:

***作品!太好了,现在我可以用它来实现我的公用表表达式。 (我不认为视图是神奇的,我只是希望能够操纵查询优化器不递归到我的 CTE 中......)

以上是关于SQL Server 2008:将 VIEW 与其他 VIEW 联接:预先计算而不求助于临时表的主要内容,如果未能解决你的问题,请参考以下文章

Sql Server 2008 视图中的 ORDER BY

sql server 2008怎么修改视图中的字段属性!!例如修改字段名和字段类型!

如何使用 SQL 将 Sql Server DateTime 转换为通用时间

将 SQL Server 2008 r2 降级到 SQL Server 2008

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

在 SQL Server 2008 视图中跨列计算特定值