茫茫網海中的冷日 - 對這文章發表回應
茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1671893 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
F09_711.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

對這文章發表回應

發表限制: 非會員 可以發表

發表者: 冷日 發表時間: 2023/5/17 8:38:50

巧用SQL實現查詢的高效分頁

2019-11-10  由 網雲技術 發表于 程式開發

朋友們,我們學習和使用資料庫技術時,是否常常會感覺,SQL就那些基礎語法,掌握了自己基本都可以無所不能了。有些朋友可能會為自己的自負栽跟頭了,比如別人寫的查詢運行很快,而自己寫的速度卻非常慢。

. . .

簡單的SQL查詢隱藏了很深的玄機

表面看,不就是select查詢嘛,so easy,還有誰比誰更先進的。但事實卻總不是這樣,就算是簡單如select,都包含了無窮的玄機。

當然,導致查詢速度慢的原因有很多,比如主鍵的設置和使用、join的合理應用、只返回必要的欄位列表等等。這些查詢優化的方法可能一本書都寫不完。

我們今天要講的,主要是如何巧妙使用分頁技術加快查詢響應的速度。所謂分頁,當然是把海量的數據(比如1000萬條),按照固定的頁大小(比如1000條),根據需要分多次(比如1萬次)返回。


. . .

如果我們面對的數據行數只有幾十條數百條,分頁就沒有什麼明顯的意義了,但如果是數十萬、數百萬行呢,如果您不分頁一次性返回,有沒有必要另說,哪像蝸牛一樣的速度絕對會讓您懷疑人生。

特別是在手機APP中,我們一般通過手指上滑獲取更多(其實是下一頁)數據,完全不需要一次性完整返回。分頁速度快,用戶的體驗當然要更好。

還好主流的資料庫都支持分頁查詢,但不同資料庫的分頁方法稍有不同,下面著重講解下SQL Server、MySQL和PostgreSQL三種主流資料庫的分頁語法和具體應用。

SQL Server的專業分頁語法

SQL Server從2012版本開始,提供了一種專注於分頁查詢的語法支持,其語法格式為:


offset m rows fetch next n rows only

其中m的含義為記錄起始行前一條記錄的行標,n的含義為返回記錄的行數。

. . .

如果我們定義@pageindex為頁碼,@pagesize為頁大小,其常用的語法格式一般為:


select 欄位列表 from 表
order by 排序欄位
offset (@pageindex-1)*@pagesize rows fetch next @pagesize rows only;

這裡,頁碼@pageindex代表第幾頁(從1開始),頁大小@pagesize代表每頁的記錄條數。

SQL Server分頁語法應用案例

我這裡準備了一個有16萬條記錄的淘寶熱詞表,我們按每頁100條記錄查詢,測試下運行效果,腳本如下:


declare @pageindex int=1;
declare @pagesize smallint=100;
select t1.*
from dwordhot t1

order by isnull(t1.fhotcount,0) desc

{!-- PGC_COLUMN --}

offset (@pageindex-1)*@pagesize
rows fetch next @pagesize rows only;

運行效果如下:

. . .

分頁查詢耗用時間是33毫秒,如果不分頁,速度就差多了,如下圖所示:

. . .

完整查詢耗用時間15951毫秒,差別不是一般的大。對於大數據量查詢的情況,查詢不分頁,簡直就是自找苦吃。

MySQL的專業分頁語法

MySQL的查詢分頁的非常簡單,要用到limit關鍵字,其語法格式為:


limit m,n

其中m的含義為起始索引(從0開始),n的含義為取n條數據,結合頁碼和頁大小,其語法格式一般體現為:


select 欄位列表 from 表
limit (@pageindex-1)*@pagesize, @pagesize;

. . .

MySQL分頁比較簡潔易懂,這裡不再舉例。

pgSQL的專業分頁語法

PostgreSQL的查詢分頁也支持offset關鍵字,但語法格式與SQLServer不太相同,同時她也支持limit關鍵字,似乎是綜合了SQLServer和MySQL語法。其語法格式為:


limit n offset m

其中n的含義為獲取的記錄條數,m的含義為查詢的起點位置(從0開始),結合頁碼和頁大小,其語法格式一般體現為:

. . .
select 欄位列表 from 表
limit @pagesize offset (@pageindex-1)*@pagesize

pgSQL的分頁語法應用案例


我這裡準備了一張表snnavi,存入1萬條記錄,腳本如下:


do $$
declare
vtest integer := 1;
begin
while vtest < 10000 loop
vtest = vtest+1;
insert into snnavi(fncsid,fnaviid)
values ( 9501, vtest);
end loop;
end $$;
select * from snnavi;

查詢耗時結果參看下圖:

. . .

如果我們使用分頁的方式返回第一頁的100行,速度就飛快了,如下圖所示:

. . .

其它分頁方式

如果您的查詢數據量比較大,強烈建議您使用分頁技術,而且儘量採用專業的推薦分頁方式,既然是專業的,這效率肯定是槓槓的。

除了上述的專業方式,我們還可以使用其它非專業的分頁方式。比如在SQLServer中,使用top、row_number、over等關鍵字,也可以實現查詢分頁,使用得當時其運行的效率與專業模式相差無幾。

如果您有興趣了解,可參看我之前寫的文章《如何在SQLServer查詢中實現高效分頁》。

. . .

無論何種方法,既然要分頁,就要知道行的起點,根據起點結合top、order by等關鍵字截取相應區間的記錄。如果您的表設置有整數遞增欄位,使用


where id>=起點 and id<=終點

會更加直觀,但並不是所有的表我們都會這樣做,所以掌握專業的分頁語法還是非常必要

的。


原文出處:巧用SQL實現查詢的高效分頁 - 每日頭條
內容圖示
url email imgsrc image code quote
樣本
bold italic underline linethrough   












 [詳情...]
validation picture

注意事項:
預覽不需輸入認證碼,僅真正發送文章時才會檢查驗證碼。
認證碼有效期10分鐘,若輸入資料超過10分鐘,請您備份內容後,重新整理本頁並貼回您的內容,再輸入驗證碼送出。

選項

Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|