精品综合在线_精品国产乱码久久久久久88av_成人在线观看av_免费一区二区三区_成人免费视频观看视频_翔田千里亚洲一二三区_91精品国自产在线观看_成人激情av_精品国产福利_国产日韩精品推荐

技術知識
NEWS CENTRE
首頁
>
新聞中心
>
實現分頁查詢pgsql方法
實現分頁查詢pgsql方法
2021-08-13 閱讀:3031

廢話不多說了,看代碼吧~

select
  row_number() over(order by 業務號,主鍵,排序號) rn -- 行號
  ,count(0) over() cnt -- 總條數
  ,id

from 表

order by 排序號,主鍵,業務號

offset (頁號- 1)* 每頁數量 limit 每頁數量

補充:postgreSQL單表數據量上千萬分頁查詢緩慢的優化方案

故事要這樣說起,w是一個初入職場的程序猿,每天干的活就是實現各種簡單的查詢業務,但是鐵蛋有一顆熱愛技術的心,每天都琢磨著如何寫出花式的增刪改查操作。沒錯平凡的鐵蛋的有著一個偉大的夢想,成為一名高級CRUDER。

時間就這樣一天天的流逝,w感覺不管自己的crud寫的再花騷也不能達到高級cruder的級別,于是乎w心一橫,接下了一個艱巨的任務,對單表數據量到百萬千萬級別的查詢頁面進行優化,這是w工作任務上的一小步,卻是w實現夢想的一大步。

接任務簡單,做任務難呀! 這是w第一天的感受,接了這個任務之后w沒有一點頭緒,從哪下手呢?w仔細一想既然要優化,那么總得知道 哪里需要優化吧? 可以從哪些方面優化吧? 需要知道最如何分析瓶頸在哪吧? 不料天降神圖,給了一個指引, 沒錯就是數據庫可以優化的方向圖。

注:圖中效果的漸變其實不太準確, 但是總的來說如果不是SQL寫的特別爛的話大體上優化這些不同的方面對性能的影響是以圖中的示意變化的。

雖然有了神圖的指引,但是w還是不知道應該優化哪個方面? 不同方面的優化方式是什么?一番努力查找,得到了以下信息:

從成本方面考慮,土豪的優化方式向來簡單粗暴,硬件不行就換硬件嘛, 不差錢!!! 但是w不行呀,草根一枚,要錢沒錢, 要人沒人,只能選擇便宜的來下手了。柿子嘛還是得挑軟的捏,于是乎,w躊躇滿志的找產品商量改需求。

咳咳 !!!!怎么說呢? w為了降低成本,為公司控本降費,初心是好的,但是呀這個做法嗯嗯啊啊。。。, 大家以此為戒哦!!!

既然改需求不行,那就只能往下走了, 先來一波SQL優化看看,要優化SQL總得知道SQL慢在哪里了吧?

咋辦咋辦! 不知道哪里慢咋辦?

還能咋辦,看SQL的執行計劃唄!

不會看咋辦?

啥! 不會看, 不會看學啊!

好吧,當我沒問!!!

怎么看執行計劃呢,首先你得會一個SQL的命令,叫EXPLAIN, 此命令用于查看SQL的執行計劃。得此命令,鐵蛋如獲至寶, 拿起來就是一頓操作,看到命令輸出的結果后,w傻眼了,這什么鬼? 這怎么看?

怎么看??? 用眼睛看唄,還能怎么看。

總的來說sql的執行計劃是一個樹形層次結構, 一般來說閱讀上遵從層級越深越優先, 同一層級由上到下的原則。

來跟著讀: 層級越深越優先, 同一層級上到下。

順序知道了,得知道里面的意思了吧, 是的沒錯, 但是這個里面比較具體的一些細節這里就不再展開了,只介紹比較常關注的幾個關鍵字:

重點來了,重點來了,睡覺的玩手機的停一停。老師要開車了, 啊呸, 開課了。

第一行的括號中從左到右依次代表的是:

(估計)啟動成本,在開始輸出之前花費的時間,例如排序時間。

(估計)總成本, 這里有一個前提是計劃節點會完整運行,即所有可用行都會被檢索。實際上一些節點的父節點不會檢索所有可用行(如LIMIT)。

(估計)輸出的總行數,同樣的是基于節點會完整運行的假設。

(估計)輸出行的平均寬度(以字節為單位)

注意:

cost中描述的是啟動成本和總成本,但是到目前為止我們還不知道這個數字代表的具體含義,因為我們不知道它的單位是什么。(所以說這里cost中的成本是具有相對意義,不具有絕對意義)

rows代表的是輸出的總行數,他不是計劃節點處理或掃描的行數,而是節點發出的行數。由于使用where子句過濾,這個值通常小于掃描的數目。理想情況下,頂級的rows近似于實際的查詢返回,更新或刪除的行數

上圖中的 Index Scan代表索引掃描, Index Cond代表索引命中,后面是命中的具體的索引; Filter是過濾條件,跟具體的sql有關, 注意sort, sort中應該是有兩行,下面的圖示中能夠看到, 第一行代表對那個鍵進行排序, 第二行是排序方法(主要有內存排序和磁盤排序,應該避免磁盤排序)和數據大小。

explain還有兩個比較有用的參數一個是analyze, 一個是buffers。 加上第一個參數可以讓sql真正的執行并且預估執行時間, 第二參數可以查看緩存命中情況。

actual time對應的意義和cost相似,但是不同于cost, actual time具有絕對意義,因為它的單位是ms。loops代表循環的次數。

緩存命中情況主要看Buffers這一行, hit就是命中情況,buffers的信息有助于確定查詢的哪部分是IO密集型的。

Hash節點主要看 Buckes, 哈希桶的數量, Batches:批處理的數量,批處理的數量如果超過1,則還會使用磁盤空間,但不會顯示。 Memory Usage代表內存的使用峰值。

有了以上信息我們基本上就可以尋醫問藥, 對癥下藥了, 該建索引的建索引, 查詢語句沒有命中索引的調整下sql,聯合索引條件過濾包含驅動列,且驅動列在前效率最高。

索引優化小技巧:

索引盡量建在數據比較分散的列上, 不要在變化很小的字段上加索引,比如性別之類的。

原因就是:

索引本質上是一種空間換時間的操作,通過B Tree這種數據結構減少io的操作次數以此來提升速度。如果在變化很小的字段上建立索引,那么可能單個葉子節點上的數據量也是龐大的,反而增加了io的次數(如果查詢字段有包含非索引列,索引命中之后還需要回表)

到了這里就開始我們題目中的正文了, 分頁查詢性能優化!!!

怎么優化呢? 經過上述一系列的索引和sql優化之后,鐵蛋老師發現雖然sql的執行速度比以前快了,但是在單表一千萬的量級下,這個查詢的速度還是有點龜速呀。

仔細看了上圖中的執行計劃發現有三個個地方有嫌疑,一個是Hash節點, 一個是Sort, 還有一個是Buffers。

在Hash節點中Batches批處理的數量超過了1, 這說明用到了外存, 原來是內存不夠了呀!

Sort節點中,排序方法是歸并, 而且是磁盤排序, 原來也是內存不夠了。

Buffers 節點中,同一個sql執行兩次每次都有新的io,說明緩存空間也不夠,最終這三個現象都指向了內存。

w打開pg的配置文件一看, 我靠,窮鬼呀,才分配了512MB的共享緩存總空間, 進程單獨分配了4M空間用于hash,排序等操作,用于維護的分配了512MB。

這哪行,再窮不能窮內存呀! 內從都沒有怎么快,怎么快!

一看,服務器有64GB的內存,恨不得都分過去,還好旁邊的y阻止了他。

y說不是這么玩的, 共享緩存區的內存一般分配是內存的1/4,不超過總內存的1/2。 線程內存就看著給了,預計下峰值連接數和均值連接數,做一個權衡,適當提高。

于是w將共享緩存區的內存分配為20GB, 單個線程用于hash和排序的分配了200MB。 重啟數據庫, 跑了下執行計劃。 sql里面從以前的一分鐘,四五十秒變成了三四秒左右。

仔細看了下執行計劃, sort中的磁盤排序變成了內存排序,排序方法從歸并變成了快排。 Hash節點中批處理的數量也變成了1, Buffers中緩存全部命中。

到了這里優化看似就完成了,但是還有些不太圓滿。 哪里不圓滿呢? 明明sql的分頁查詢語句很快,為什么頁面上的分頁查詢還是要四五秒呢?

一拍腦袋,怎么把這個給忘了, 分頁查詢頁面有個總數統計, 總數統計的sql也需要占時間的呀? 怎么辦?

有辦法, 不要慌? 我們的原則就是兩條腿走路,兩個方針政策。

優化全表掃描的速度 (為什么要優化全表掃描的速度,因為統計總數的時候大多數情況下是不能避免全表掃描的)分頁查詢和統計的sql并行執行怎么實行?

優化全表掃描的速度還得從服務器下手, 全表掃描慢是因為服務器的IO慢,鐵蛋恨不得把這個82年的機械硬盤換成SSD,但是人微言輕,只能從其他方面下手: 調大IO預讀的大小

#查看當前預讀大小
blockdev --getra /dev/vda
#設置預讀大小 , 4096的單位是扇區,即512bytes
blockdev --setra 4096 /dev/vda

 

注意:上面的命令在服務器重啟之后失效,所以想永久生效需要將此命令放到 /etc/rc.local 開機自啟動腳本中。

sql并行化的實現也比較容易,在一開始就向線程池提交一個統計sql'的任務, 等到分頁查詢的數據處理完成最后要返回給前端之前找線程池要總數就行了,如果沒有執行完,會阻塞等待執行完,所以響應時間就可以控制在sql執行時間最長的那段時間之內了。

至此優化任務算是完成個七七八八了,但是w突然手一抖點了最后一頁,哎發現怎么最后一頁查詢的速度要比第一頁慢上一些,怎么回事?

因為如果sql涉及到針對某個字段的排序,那么往后翻頁的時候如果采用的是limit offset 的方式會變得很慢,因為數據庫需要先把前面的數據都讀出來然后扔掉前面不需要的。這個時候一般情況下沒有太多sql上的技巧可以優化了,只有在某些個特殊情況下可以采用一些小技巧。

方法是錨點定位法或者叫點位過濾,差不多就這個叫法,知道意思就行。

這個定位是怎么做的呢,如果當你的查詢不帶過濾條件, (比如你的個人訂單記錄,只是比較下,不要細糾)。且你的數據中有一個遞增且連續的字段(注意一定要連續),那么就可以通過翻頁前的最后一條數據的id來定位下一頁的位置, 或者直接根據分頁大小和要跳轉的頁碼直接定位到你要翻頁的地方,一般情況下這個字段是主鍵。

示例:

select id, time from a order by time limit 10 offset 1000;
//錨點定位就是
select id, time from a where id in (select id from a where id > 1000 limit 10)
order by time
//或者直接
select id, time from a where id > 1000 order by time limit 10

 

寫在最后老師的忠告, 如果在某些情況下通過某個索引去查詢的時候因為數據離散存儲導致的索引命中之后回表IO放大導致查詢緩慢的問題,可以通過CLUSTER 命令強制數據按照某個索引的順序密集存儲。

1cluster a using index_name

如何查看數據是不是離散存儲,很簡單!! 在selec語句中加上ctid字段。

ctid | id
-------+----
 (0,1) | 10
 (0,2) | 11

ctid的第一個數字代表塊號, 第二個代表行號, 就是第幾塊的第幾行, 所以通過此字段就能看出離散程度。


13560189272
地址:廣州市天河區黃埔大道西201號金澤大廈808室
COPYRIFHT ? 2010-2020 廣州市名聯網絡科技有限公司 ALL RIGHTS RESERVED 粵ICP備10203057號
  • 這里是二維碼
精品综合在线_精品国产乱码久久久久久88av_成人在线观看av_免费一区二区三区_成人免费视频观看视频_翔田千里亚洲一二三区_91精品国自产在线观看_成人激情av_精品国产福利_国产日韩精品推荐
中文字幕一区二区三区四区在线视频| 好吊色视频在线观看| 在线免费观看av网址| 国产破处视频在线观看| 亚洲国产成人精品一区二区三区 | av在线播放网址| 色综合久久久久久| 久久综合色综合| www.国产黄色| 91麻豆精品在线| 五月天婷婷网站| 欧美熟妇激情一区二区三区| 国产在线a视频| 国产午夜免费视频| 国产欧美久久久精品免费| 国产黄色大片网站| 国产精品视频123| 国产精品16p| 国产丝袜在线视频| 精品人妻伦一二三区久| 国产亚洲第一页| www.中文字幕av| 99久久精品无免国产免费| 136福利视频导航| 夜夜骚av一区二区三区| 中文字幕视频三区| 97人妻精品一区二区免费| 4438国产精品一区二区| 中文字幕在线2021| 91久久久久久久久久久久| av在线播放中文字幕| 国产叼嘿视频在线观看| 国产又大又黄的视频| 六月婷婷七月丁香| 少妇精品无码一区二区| 在线视频欧美亚洲| 国产成人精品一区二三区四区五区| 国产伦精品一区二区三区视频痴汉| 国内毛片毛片毛片毛片毛片| 日韩av一区二区在线播放| 天堂在线一区二区三区| 亚洲精品国产精品乱码| www.涩涩涩| 国产免费一级视频| 人妻体内射精一区二区三区| 中文字幕天天干| 国产麻豆剧传媒精品国产av| 久久久精品视频网站| 少妇人妻一区二区| 99久久婷婷国产一区二区三区| 国产三级午夜理伦三级| 久久久久久久久久久97| 视频区 图片区 小说区| 亚洲欧美色图视频| 国产青青草视频| 视频免费1区二区三区| 91久久免费视频| 欧美丝袜在线观看| 亚洲中文字幕一区二区| 国产一区二区三区影院| 午夜影院在线看| 粉嫩aⅴ一区二区三区| 欧美一区二区三区观看| www.久久精品.com| 人人妻人人澡人人爽人人精品| 亚洲成人av免费在线观看| av在线免费播放网址| 人妻精品久久久久中文| av中文字幕第一页| 熟妇人妻中文av无码| 国产欧美一区二区三区在线看蜜臂 | 嫩草影院一区二区三区| 中文字幕一区二区在线视频 | www.97av.com| 日本在线视频中文字幕| 一级 黄 色 片一| 青娱乐国产精品| 国产精品国产一区二区三区四区| 天天影视色综合| 九九热国产视频| a级在线免费观看| 伊人五月天婷婷| 人妻精品一区二区三区| 国产黄色大片网站| 五月婷婷亚洲综合| 免费观看成人毛片| 国产人成视频在线观看| 亚洲熟妇一区二区三区| 日韩欧美亚洲视频| 久久久久久蜜桃| 国产日本精品视频| www.天天干.com| 中文字幕人妻色偷偷久久| 久久久久亚洲av成人无码电影| av永久免费观看| 中文字幕在线视频第一页| 嫩草影院一区二区| 精品国产午夜福利| 国产一级二级av| 成人午夜视频一区二区播放| 亚洲精品综合网| 中文无码av一区二区三区| 日本一级免费视频| 久久久久久久黄色片| 国产绿帽一区二区三区| a级黄色片免费看| 91精品国产色综合久久不8| 一区二区三区精彩视频| 五月婷婷六月丁香激情| 五月婷婷激情视频| 日韩中文字幕免费在线观看| 日韩av一区二区在线播放| 欧美视频久久久| 欧美成人三级伦在线观看| 九九在线观看视频| 久久久久久久久97| 欧美特黄一级视频| 蜜桃精品一区二区| 人人妻人人澡人人爽人人精品| 欧美激情精品久久| 日韩免费观看一区二区| 人妻少妇精品一区二区三区| 免费人成视频在线| 人人爽人人av| 天天色天天干天天色| 中文字幕欧美人妻精品| 97在线观看免费视频| 国产精品久久久视频| 精品无码人妻一区| 久久久久久无码精品大片| 久久久精品视频网站| 欧美熟妇精品一区二区| 天天干天天操av| 69成人免费视频| 国产性xxxx| 少妇av一区二区| 999久久久精品视频| 国产一区第一页| 色婷婷一区二区三区在线观看 | 日本激情综合网| 亚洲av无码一区二区三区性色| 中文字幕有码在线播放| 99精品中文字幕| 精品国产欧美日韩不卡在线观看| 日韩一级片免费在线观看| 中文字幕色网站| 国产一区二区三区视频播放| 色偷偷男人天堂| www国产一区| 免费在线黄色网| 亚洲精品一区二区二区| 黄色成人免费看| 怡红院一区二区| 狠狠人妻久久久久久| 午夜精品一区二区三级视频| 福利视频第一页| 日本熟妇一区二区| 亚洲黄色小说在线观看| 精品人妻av一区二区三区| 中文在线a天堂| 欧美熟妇精品黑人巨大一二三区| 亚洲少妇一区二区三区| 黄色一级大片在线免费看国产| 亚洲AV成人无码网站天堂久久| 国产精品日日摸夜夜爽| 中文字幕精品一区二区三区在线| 国产探花在线视频| 亚洲av成人片色在线观看高潮 | wwwwww在线观看| 蜜桃色一区二区三区| 亚洲一区精品在线观看| 久久免费看少妇高潮v片特黄| 在线免费观看国产精品| 蜜桃av噜噜一区二区三区麻豆| 18禁一区二区三区| 日韩欧美综合视频| 黄色一级大片在线免费看国产 | 亚洲 另类 春色 国产| 国产精品第6页| 中文 欧美 日韩| 男操女免费网站| 国产又爽又黄又嫩又猛又粗| 亚洲 欧美 日韩系列| 久久久久久久久精| 国产一二三四五区| 国产123在线| 亚洲精品乱码久久久久久蜜桃图片| 男人午夜免费视频| 韩国视频一区二区三区| www.国产麻豆| 99国产精品久久久久久| 伊人久久国产精品| 亚欧精品在线视频| 日日干夜夜操s8| 女教师高潮黄又色视频| 伦av综合一区| 男人的天堂av网站| 韩国av中文字幕| 精品视频站长推荐| 国产精品人人人人|