2011-03-17 69 views
5

在stackoverflow上有很多sql server分頁問題,​​他們中的很多人都在談論使用ROW_NUMBER() OVER (ORDER BY ...) AND CTE。一旦進入成千上萬的行並開始在非主鍵值上添加排序並添加自定義的WHERE子句,這些方法就會變得非常不便。我有一個包含數百萬行的數據集,我試圖通過自定義排序和篩選來進行翻頁,但是我的性能很差,甚至在我排序和篩選的所有字段上都有索引。我甚至儘可能在每個索引中包含我的SELECT列,但這幾乎沒有幫助,並嚴重臃腫了我的數據庫。Microsoft SQL Server尋呼

我注意到,無論您點擊什麼排序標準或頁碼,stackoverflow分頁只需要大約500毫秒。任何人都知道如何在數百萬行的SQL Server 2008中高效地進行分頁工作?這將包括儘可能有效地獲取總行數。

我的當前查詢具有完全相同的邏輯有關尋呼這個計算器的問題: Best paging solution using SQL Server 2005?

+0

您可以發佈查詢的任何機會;一般原則是一個很好的人,但他在現實世界中存在問題;) – u07ch 2011-03-17 07:14:00

+0

不在每個想要排序(或篩選)的列上添加索引,有幫助嗎?這似乎很明顯,但我不知道你是否嘗試過。 – bart 2011-03-17 08:05:53

+0

我確實在所有列上都有索引。超過前幾千的分頁後,查詢時間開始線性上升... – jjxtra 2011-06-14 05:36:29

回答

5

任何人都知道如何使呼叫有效地工作在SQL Server 2008與數百萬行的?

如果您想要精確完美的分頁,那麼爲每個記錄建立一個索引鍵(位置行號)是不可替代的。但是,還有其他選擇。

(1)總頁數(記錄)

  • 您可以使用近似從sysindexes.rows(幾乎即時)假設的變化率小。
  • 可以使用觸發器來保持一個完全準確的,到第二,表中的行數

(2)尋呼

(一)
可以顯示頁面跳轉中說,在未來五年頁在記錄的任何一邊。這些需要在每邊最多掃描{頁面大小} x 5。如果您的基礎查詢適合快速沿着排序順序旅行,這應該不會太慢。因此,考慮記錄X,你可以使用到前一個頁面(假設排序順序是a asc, b desc

select top(@pagesize) t.* 
from tbl x 
inner join tbl t on (t.a = x.a and t.b > x.b) OR 
        (t.a < a.x) 
where x.id = @X 
order by t.a asc, t.b desc 

(即最後的前X個記錄)

{頁面大小}若要去五頁回,您將其增加到TOP(@ pagesize * 5),然後再從該子查詢中進一步選擇TOP(@pagesize)。

缺點:此選項要求您無法直接跳轉到特定位置,您的選項只有第一(簡單) ,LAST(easy),NEXT/PRIOR,<每頁5頁

(b)
如果分頁總是非常具體和可預測的,請維護INDEXED視圖或觸發器更新的表,該表不包含行號中的空位。如果表格通常只能看到頻譜一端的更新,那麼這可能是一種選擇,通過移動不太多的記錄可以快速輕鬆地填充刪除的差距。

這種方法爲您提供了一個rowcount(最後一行),也可以直接訪問任何頁面。

+0

這是非常深思熟慮的,謝謝我會嘗試一些這些東西 – jjxtra 2011-03-17 08:16:41

+1

當結果總數較小(小於100K)時,我最終做的是使用我的Lucene索引進行分頁。當它更高時,我使用SQL Server。 Sql服務器在大表中尋找分頁小結果集。 Lucene非常適合在較大的數據集中分頁較小的結果集。 – jjxtra 2012-02-13 18:32:18

+0

不妨將此標記爲正確,因爲它與使用SQL Server時可以獲得的一樣好。我上面提到的混合方法工作得很好。 – jjxtra 2012-05-25 21:14:40