首页 文章

在视图中使用row_number(partition by ...)无休止地运行vs作为查询运行

提问于
浏览
1

我的任务是增强SQL视图以提高性能,该代码的伪代码如下所示 . 它有row_number(分区依...按...排序),这似乎导致此视图无限期运行,直到我终止查询 . 即当我运行 select * from view_name where Date = '2015-01-31' 时,它会永远运行 . 但是如果我将整个视图作为查询运行(例如,在顶部删除alter view语句并在代码末尾传递where子句),它运行正常 .

我正在使用SQL 2005.可能SQL 2005引擎为视图与普通查询生成不同的执行计划,因为我提到视图中的整个代码,当作为查询执行时,运行正常 . 如何让视图本身运行得更快,以便返回结果?我的视图查询的其中一个表(此伪代码中的table1)非常大,并按日期分区,其中每个月的数据是一个分区 .

伪代码:

CREATE VIEW Sample
AS
WITH Dataset1
AS (
    SELECT table1.DATE
        ,column1
        ,column2
        ,column3
        ,column4
    FROM table1
    INNER JOIN table2 ON table1.DATE = table2.DATE
    )
    ,Dataset2
AS (
    SELECT Dataset1.DATE
        ,column1
        ,column2
        ,column3
        ,column4
    FROM table3
    INNER JOIN Dataset1 ON table3.column1 = Dataset1.column1
    )
SELECT ROW_NUMBER() OVER (
        PARTITION BY column1 ORDER BY column1 ASC
        ) AS RowNumber
    ,*
FROM Dataset2
GO

1 回答

  • 2

    我改进此查询的第一步是:

    • 降低代码复杂性:为什么使用两个CTE?从示例代码中可以看出,这可以重写为连接表1到2,然后是2到3的单个查询,ROW_NUMBER()直接在SELECT子句中 . 这可能不会直接影响性能,但分析简单查询比复杂查询要容易得多 .

    • 重新考虑ROW_NUMBER()的预期行为:您正在按同一列进行分区和排序 . 这意味着对于column1中的每个不同值,SQL Server将尝试根据column1中的值对行进行排序;这个值在该分区内都是相同的,因此排序基本上是“随机的”,浪费了任何专门用于此的处理时间 . (主要取决于其他因素,例如这些表上的任何聚簇索引 . )

    • 检索此查询的执行计划并检查它以获取更多想法 . 执行计划可能包括可以应用的索引的提示 - 您应该考虑这些提示,但不要将SQL Server的单词作为福音 .

    如果我能看到执行计划,对这些表的结构有更深入的了解(包括关系的索引和基数),并且知道“非常大”对你意味着多大,我可能会有进一步的建议:)

相关问题