2009-08-06 86 views
1

我在想这样的查询是否可能被优化。 我极大地简化了它,并且你看到了它的核心。SQL Server 2005中的SQL查询优化(CTE +范围函数)

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 

它所做的是分层次查询desendent部门,然后对其进行测量。

我最终得到一个巨大的执行计划,并想知道它是否可以以不同的方式完成。

谢谢。

回答

1

我quess这可能是一个好一点给出如下假设:

  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 
+0

亚历克斯,帮助表示感谢。我已经有了我的ParentId索引,并且您的选项产生0.21的子树成本,而我的0.17。 – Valentin 2009-08-07 06:42:02

+0

它发生了(提议的更改没有帮助)。 我只是想知道:你比较了这个“简单案例”或原始(复杂,真实世界)查询的子树的成本?我猜结果可能会有很大的不同。 – AlexS 2009-08-07 17:57:21