[搜片神器]服務器SQL2005查詢分頁語句你理解了麼

sosobt.com網站準備採用Lucence.net來進行索引處理搜索慢問題的時候,忽然發現經常使用的分頁獲取數據的row_number也支持不住了,後期查到200多萬的時候很是慢(總數據有500萬),通過網上查詢分析一些資料後,基本上搞明白是什麼緣由致使的,順便紀錄一下解決方案。sql

------------------------------------數據庫

網上找的幾種sqlserver2005高效分頁sql查詢語句
top方案:
sql codeselect top 10 * from table1
where id not in(select top 開始的位置 id from table1)服務器

max:
sql codeselect top 10 * from table1
where id>(select max(id)
from (select top 開始位置 id from table1order by id)tt)sqlserver

row:
sql codeselect *
from (
select row_number()over(order by tempcolumn)temprownumber,*
from (select top 開始位置+10 tempcolumn=0,* from table1)t
)tt
where temprownumber>開始位置
3種分頁方式,分別是max方案,top方案,row方案學習

效率:
第1:row
第2:max
第3:top測試

缺點:
max:必須用戶編寫複雜sql,不支持非惟一列排序
top:必須用戶編寫複雜sql,不支持複合主鍵
row:不支持sqlserver2000優化

測試數據:
共320萬條數據,每頁顯示10條數據,分別測試了2萬頁、15萬頁和32萬頁。網站

頁碼,top方案,max方案,row方案
2萬,60ms,46ms,33ms
15萬,453ms,343ms,310ms
32萬,953ms,720ms,686msspa

-----------------------------------------------.net

我的也是常常採用row_number來解決問題的,可是主鍵是以ID爲主的,此次數據庫表不是ID主鍵,

若是使用ID來進行獲取200萬後面的200條數據,發現服務器上須要幾分鐘都不必定出來得結果

select * from (select *,row_number() over(order by ID asc) as RowNum from H31_DHT_TYPE_101_1) as a where RowNum between 2000000  and  2000200

可是使用HashKey來排序,則很快,ms表示毫秒

select * from (select *,row_number() over(order by hashkey asc) as RowNum from H31_DHT_TYPE_101_1) as a where RowNum between 2000000  and  2000200
[2013-10-13 7:32:02]: Addindex[1011]:1500601 DBTime:219ms IndexTime:47ms
[2013-10-13 7:32:02]: Addindex[1011]:1500801 DBTime:219ms IndexTime:31ms
[2013-10-13 7:32:03]: Addindex[1011]:1501001 DBTime:547ms IndexTime:687ms
[2013-10-13 7:32:04]: Addindex[1011]:1501201 DBTime:219ms IndexTime:94ms
[2013-10-13 7:32:04]: Addindex[1011]:1501401 DBTime:219ms IndexTime:31ms
[2013-10-13 7:32:04]: Addindex[1011]:1501601 DBTime:219ms IndexTime:62ms
[2013-10-13 7:32:04]: Addindex[1011]:1501801 DBTime:219ms IndexTime:31ms
[2013-10-13 7:32:05]: Addindex[1011]:1502001 DBTime:219ms IndexTime:78ms
[2013-10-13 7:32:05]: Addindex[1011]:1502201 DBTime:219ms IndexTime:47ms
[2013-10-13 7:32:05]: Addindex[1011]:1502401 DBTime:218ms IndexTime:32ms

因爲hashkey是惟一,但不是遞增的問題,必須以ID遞增來獲取紀錄增長到lucence索引裏面,

在此查詢了什麼時候使用匯集索引或非彙集索引


下面的表總結了什麼時候使用匯集索引或非彙集索引(很重要):

 

動做描述 使用匯集索引 使用非彙集索引
列常常被分組排序
返回某範圍內的數據 不該
一個或極少不一樣值 不該 不該
小數目的不一樣值 不該
大數目的不一樣值 不該
頻繁更新的列 不該
外鍵列
主鍵列
頻繁修改索引列 不該

 

  主鍵 彙集索引
用途 強制表的實體完整性 對數據行的排序,方便查詢用
一個表多少個 一個表最多一個主鍵 一個表最多一個彙集索引
是否容許多個字段來定義 一個主鍵能夠多個字段來定義 一個索引能夠多個字段來定義
     
是否容許 null 數據行出現 若是要建立的數據列中數據存在null,沒法創建主鍵。
建立表時指定的 PRIMARY KEY 約束列隱式轉換爲 NOT NULL。
沒有限制創建彙集索引的列必定必須 not null .
也就是能夠列的數據是 null
參看最後一項比較
是否要求數據必須惟一 要求數據必須惟一 數據便可以惟一,也能夠不惟一。看你定義這個索引的 UNIQUE 設置。
(這一點須要看後面的一個比較,雖然你的數據列可能不惟一,可是系統會替你產生一個你看不到的惟一列)
     
建立的邏輯 數據庫在建立主鍵同時,會自動創建一個惟一索引。
若是這個表以前沒有彙集索引,同時創建主鍵時候沒有強制指定使用非彙集索引,則創建主鍵時候,同時創建一個惟一的彙集索引
若是未使用 UNIQUE 屬性建立彙集索引,數據庫引擎 將向表自動添加一個四字節 uniqueifier 列。
必要時,數據庫引擎 將向行自動添加一個 uniqueifier 值,使每一個鍵惟一。此列和列值供內部使用,用戶不能查看或訪問。

 

經過此處分析聚焦索引一個表只能有一個,如何解決目前的問題呢?

首先咱們分析下

select * from (select *,row_number() over(order by ID asc) as RowNum from H31_DHT_TYPE_101_1) as a where RowNum between 2000000  and  2000200

這條語句的對與錯的問題,

1.select *,row_number() over(order by ID asc) as RowNum from H31_DHT_TYPE_101_1代表了須要查詢全部字段和列所有搜索出來了,數據小的時候你不會發現,但數據量大的時候就知道了,由於他代表了獲取全部字段的數據進行按ID排序,雖然ID也索引了。

2.上面須要很長時間,而後再去定位查詢感受時間很慢。

因此我的的想法是先不用查詢出全部字段的數據,

WITH temp AS (SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS 'RowNumber' FROM H31_DHT_TYPE_101_1)

這條語句查詢出來的結果須要1到2秒,比起上面的基本上須要很長時間算是好的了,

而後再從這裏面取ID號,這樣就節約了很多時間,

WITH temp AS (SELECT id, ROW_NUMBER() OVER (ORDER BY id) AS 'RowNumber' FROM H31_DHT_TYPE_101_1)
select ID,hashKey,recvTime,updateTime,keyContent,keyType,recvTimes,fileCnt,filetotalSize,Detail,viewTimes,viewLevel from H31_DHT_TYPE_101_1 where id in (select id from temp where RowNumber between  2000000  and  2000200) 

分析使用的時間在2秒左右

[2013-10-14 2:43:17]: Addindex[1011]:2577092 DBTime:1453ms IndexTime:32ms
[2013-10-14 2:43:19]: Addindex[1011]:2577292 DBTime:1515ms IndexTime:32ms
[2013-10-14 2:43:20]: Addindex[1011]:2577492 DBTime:1578ms IndexTime:31ms
[2013-10-14 2:43:22]: Addindex[1011]:2577692 DBTime:1687ms IndexTime:32ms
[2013-10-14 2:43:23]: Addindex[1011]:2577892 DBTime:1422ms IndexTime:31ms
[2013-10-14 2:43:25]: Addindex[1011]:2578092 DBTime:1547ms IndexTime:31ms
[2013-10-14 2:43:27]: Addindex[1011]:2578292 DBTime:1469ms IndexTime:31ms
[2013-10-14 2:43:28]: Addindex[1011]:2578492 DBTime:1516ms IndexTime:31ms
[2013-10-14 2:43:30]: Addindex[1011]:2578692 DBTime:1422ms IndexTime:31ms
[2013-10-14 2:43:36]: Addindex[1011]:2578892 DBTime:6422ms IndexTime:31ms
[2013-10-14 2:43:40]: Addindex[1011]:2579092 DBTime:3938ms IndexTime:31ms
[2013-10-14 2:43:43]: Addindex[1011]:2579292 DBTime:3484ms IndexTime:32ms
[2013-10-14 2:43:48]: Addindex[1011]:2579492 DBTime:4265ms IndexTime:32ms
[2013-10-14 2:43:50]: Addindex[1011]:2579692 DBTime:1750ms IndexTime:31ms

 

總結:                                                                                                     

1.對SQL2005的分頁進一步的瞭解了彙集索引的問題,有彙集索引的使用ROW_NUMBER則很快;

2.對目前你們所採用的分頁語句是否合理的問題,優化的問題得了學習,特此記錄一下。

3.但願寫得不對的地方請你們在此留言指教下.

下一篇準備對網站採用lucence.net3.03如何來進行索引搞定搜索的問題進行記錄。

 

你們看累了,就移步到娛樂區sosobt.com 去看看,休息下...

 

但願你們多多推薦哦...你們的推薦纔是下一篇介紹的動力...

相關文章
相關標籤/搜索