2009-08-06 84 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