【问题标题】:SQL query optimization (CTE + range function) in SQL Server 2005SQL Server 2005 中的 SQL 查询优化(CTE + 范围函数)
【发布时间】:2009-08-06 09:26:01
【问题描述】:

我想知道是否可以优化此类查询。 我已经大大简化了它,你看到了它的核心。

with Rec (Id,Name,ParentId)
as
(
    select Id,Name,ParentId from Departments where ParentId is null
    union all
    select d.Id, d.Name, d.ParentId from Departments d join Rec r on 
    (d.ParentId=r.Id)
)
select q.* from (
select ROW_NUMBER() OVER (ORDER BY r.Id DESC) AS [ROW_NUMBER], r.* from Rec r
) as q
where q.[ROW_NUMBER] between 100 and 200

它的作用是分层查询下属部门,然后对其进行测距。

我最终制定了一个庞大的执行计划,并想知道是否可以以不同的方式完成。

谢谢。

【问题讨论】:

    标签: sql sql-server-2005 common-table-expression


    【解决方案1】:

    我认为考虑到以下假设,它可能会更好一些:

    1. 您有正确的 ParentId 索引
    2. 您从表中检索到大量数据(大部分列)

    可以做什么:为了减少 io 子系统的负载,我们可以首先编写一个 Id 列表,对它们进行分页(即按 RowNumber 过滤),然后才包括所有其他列。这将有效地导致通过 ParentId 处理索引,考虑到上述两个假设,这应该会更快。

    所以这是我“亲自”提出的建议:

    with Rec (Id,ParentId)
    as
    (
        select Id,ParentId from Departments where ParentId is null
        union all
        select d.Id, d.ParentId from Departments d join Rec r on 
        (d.ParentId=r.Id)
    ),
    Paged 
    as
    (
        select * from (
            select ROW_NUMBER() OVER (ORDER BY r.Id DESC) AS [ROW_NUMBER], r.* from Rec r
        ) as q
        where q.[ROW_NUMBER] between 100 and 200
    )
    select * 
    from 
        Paged
        inner join Departments d on d.Id = Paged.Id
    

    【讨论】:

    • 亚历克斯,感谢您的帮助。我已经为我的 ParentId 编制了索引,您的选项产生 0.21 的子树成本,而我的是 0.17。
    • 它发生了(建议的更改没有帮助)。我只是想知道:您是否比较了这种“简化案例”或原始(复杂的,现实世界)查询的子树成本?我猜结果可能会有很大差异。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多