<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

別再用offset和limit分頁了,OFFSET和LIMIT有什么問題?

jf_ro2CN3Fa ? 來源:芋道源碼 ? 2023-08-11 09:37 ? 次閱讀

不需要擔心數據庫性能優化問題的日子已經一去不復返了。

隨著時代的進步,隨著野心勃勃的企業想要變成下一個 Facebook,隨著為機器學習預測收集盡可能多數據的想法的出現,作為開發人員,我們要不斷地打磨我們的 API,讓它們提供可靠和有效的端點,從而毫不費力地瀏覽海量數據。

如果你做過后臺開發或數據庫架構,你可能是這么分頁的:

wKgaomTVkSuATqrBAAA1rAwSdIU550.jpg

如果你真的是這么分頁,那么我不得不抱歉地說,你這樣做是錯的。

你不以為然?沒關系。Slack、Shopify 和 Mixmax 這些公司都在用我們今天將要討論的方式進行分頁。

我想你很難找出一個不使用 OFFSET 和 LIMIT 進行數據庫分頁的人。對于簡單的小型應用程序和數據量不是很大的場景,這種方式還是能夠“應付”的。

如果你想從頭開始構建一個可靠且高效的系統,在一開始就要把它做好。

今天我們將探討已經被廣泛使用的分頁方式存在的問題,以及如何實現高性能分頁。

1、OFFSET 和 LIMIT 有什么問題?

正如前面段落所說的那樣,OFFSET 和 LIMIT 對于數據量少的項目來說是沒有問題的。

但是,當數據庫里的數據量超過服務器內存能夠存儲的能力,并且需要對所有數據進行分頁,問題就會出現。

為了實現分頁,每次收到分頁請求時,數據庫都需要進行低效的全表掃描。

什么是全表掃描?全表掃描 (又稱順序掃描) 就是在數據庫中進行逐行掃描,順序讀取表中的每一行記錄,然后檢查各個列是否符合查詢條件。這種掃描是已知最慢的,因為需要進行大量的磁盤 I/O,而且從磁盤到內存的傳輸開銷也很大。

這意味著,如果你有 1 億個用戶,OFFSET 是 5 千萬,那么它需要獲取所有這些記錄 (包括那么多根本不需要的數據),將它們放入內存,然后獲取 LIMIT 指定的 20 條結果。

也就是說,為了獲取一頁的數據:

10萬行中的第5萬行到第5萬零20行

需要先獲取 5 萬行。這么做是多么低效?

左邊的 Schema SQL 將插入 10 萬行數據,右邊有一個性能很差的查詢和一個較好的解決方案。只需單擊頂部的 Run,就可以比較它們的執行時間。第一個查詢的運行時間至少是第二個查詢的 30 倍。

數據越多,情況就越糟??纯次覍?10 萬行數據進行的 PoC。

現在你應該知道這背后都發生了什么:OFFSET 越高,查詢時間就越長。

2、替代方案

你應該這樣做:

wKgaomTVkPuABb-4AAA80HENH3I506.jpg

這是一種基于指針的分頁。

你要在本地保存上一次接收到的主鍵 (通常是一個 ID) 和 LIMIT,而不是 OFFSET 和 LIMIT,那么每一次的查詢可能都與此類似。

為什么?因為通過顯式告知數據庫最新行,數據庫就確切地知道從哪里開始搜索(基于有效的索引),而不需要考慮目標范圍之外的記錄。

比較這個查詢:

wKgZomTVkPuAPlPRAABneBQ-sA0433.jpg

和優化的版本:

wKgaomTVkPuAGssfAACUmeiNU5Y939.jpg

返回同樣的結果,第一個查詢使用了 12.80 秒,而第二個僅用了 0.01 秒。

要使用這種基于游標的分頁,需要有一個惟一的序列字段 (或多個),比如惟一的整數 ID 或時間戳,但在某些特定情況下可能無法滿足這個條件。

我的建議是,不管怎樣都要考慮每種解決方案的優缺點,以及需要執行哪種查詢。

如果我們的表沒有主鍵,比如是具有多對多關系的表,那么就使用傳統的 OFFSET/LIMIT 方式,只是這樣做存在潛在的慢查詢問題。我建議在需要分頁的表中使用自動遞增的主鍵,即使只是為了分頁。






審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 存儲器
    +關注

    關注

    38

    文章

    7212

    瀏覽量

    162349
  • PoC
    PoC
    +關注

    關注

    1

    文章

    66

    瀏覽量

    20355
  • SQL
    SQL
    +關注

    關注

    1

    文章

    740

    瀏覽量

    43527
  • 機器學習
    +關注

    關注

    66

    文章

    8176

    瀏覽量

    130945

原文標題:別再用 offset 和 limit 分頁了,性能太差!

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    關于選型時POWER MOSFET的Id的Silicon limit和package limit的看法

    在POWER MOSFET數據手冊上,有些手冊上只標明了Silicon limit,而且這個值往往很大。請問,在實際應用時,應該參照哪一個Id值。
    發表于 12-17 10:35

    請問ADL5375的offset是指DC offset么?

    我最近在看ADL5375的芯片資料。上面提到調節LO泄露是在調IQ的offset 電壓,請問,這個offset是指DC offset么?它具體到底是指什么呢?大家一般是用LO差分輸入還是單端輸入呢?兩者結果有哪些區別?
    發表于 11-29 15:32

    OFFSET約束問題

    嗨,大家好,據我所知,OFFSET約束強加于所有輸入PAD。在我的設計中,使用了兩個時鐘輸入。因此,PAD上的輸入信號應分組為:1.需要OFFSET約束時間值#1,參考時鐘輸入#12.需要
    發表于 05-29 13:51

    千萬別再用這臺示波器,我怕你會愛上它!

    千萬別再用這臺示波器,我怕你會愛上它!
    發表于 05-30 21:01

    看看nginx的連接頻率limit_conn_module和請求頻率limit_req_module限制模塊

    : -Context: http, server, location這里個前提必須在http下先定義好limit_conn_zone才可以在這里引用。這里的zone就是上面zone的名字,number就是同一時間
    發表于 10-19 14:20

    CDMA Access pn offset與距離的公式測定

    CDMA Access_pn_offset與距離的公式測定:本文測定了Motorola CDMA系統中Access_pn_offset與距離的關系,解決了長期以來困擾無線工程師的CDMA距離判定問題。一、緒論    在移動
    發表于 07-27 21:53 ?40次下載

    Timing Groups and OFFSET Const

    Timing Groups and OFFSET Constraints: •Use the Constraints Editor to create groups of path
    發表于 01-11 08:55 ?4次下載

    Current-Limit Switch Is Digita

    Abstract: Current-limit switches are virtually ubiquitous in system controls. They provide a safe
    發表于 05-08 09:56 ?2854次閱讀
    Current-<b class='flag-5'>Limit</b> Switch Is Digita

    OFFSET約束的寫法(OFFSET IN和OFFSET OUT)

    1. OFFSET約束的寫法 Offset 約束定義了外部時鐘pad和與之相關的輸入、輸出pad之間的相對關系。這是一個基礎的時序約束。Offset定義的是外部之間的關系,不能用在內部信號
    發表于 02-08 13:22 ?1964次閱讀
    <b class='flag-5'>OFFSET</b>約束的寫法(<b class='flag-5'>OFFSET</b> IN和<b class='flag-5'>OFFSET</b> OUT)

    為什么分頁場景下mysql請求速度非常慢

    * from table where status = xx limit 10 offset 10000。會非常慢。數據量不大的情況就有幾秒延遲。 小白作答瞎猜了個log(N),心想找一個節點不就是log(N)。自
    的頭像 發表于 10-08 14:46 ?1378次閱讀
    為什么<b class='flag-5'>分頁</b>場景下mysql請求速度非常慢

    MySQL用limit為什么會影響性能

    有一張財務流水表,未分庫分表,目前的數據量為9555695,分頁查詢使用到了limit,優化之前的查詢耗時16 s 938 ms (execution: 16 s 831 ms, fetching
    的頭像 發表于 06-20 16:31 ?1289次閱讀

    offset新探索:雙管齊下,加速大數據量查詢

    眾所周知,在各類業務中時常會用到LIMIT y offset x來做跳過x條數據讀取Y條數據的操作。例如:SELECT * FROM ... LIMIT 1000 OFFSET 100
    的頭像 發表于 11-24 14:45 ?398次閱讀
    <b class='flag-5'>offset</b>新探索:雙管齊下,加速大數據量查詢

    VSync offset定義的方法

    VSync-offset/duration 虛擬化后的VSync還有一個好處,就是可以對VSync進行一些定制操作,offset就是其中之一。 接下來就是offset的定義,offset
    的頭像 發表于 11-21 16:57 ?509次閱讀
    VSync <b class='flag-5'>offset</b>定義的方法

    mybatis邏輯分頁和物理分頁的區別

    這兩種分頁方式的區別。 邏輯分頁是在數據庫中執行查詢時使用的一種分頁方式。這種方式是通過在查詢語句中添加LIMITOFFSET關鍵字來限制
    的頭像 發表于 12-03 14:54 ?510次閱讀

    oracle數據庫limit怎么用

    在Oracle數據庫中,可以使用ROWNUM來實現類似LIMIT的功能。ROWNUM是Oracle數據庫提供的一個偽列,它在查詢結果集中為每一行分配一個唯一的數字。 要使用ROWNUM進行分頁查詢
    的頭像 發表于 12-06 10:05 ?1323次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>