成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

從 12s 到 200ms,MySQL 兩千萬訂單數據六種深度分頁優化全解析

數據庫
本文將深入拆解深度分頁的技術黑箱,通過電商訂單表等真實場景,揭示 B+樹索引與分頁機制的碰撞奧秘,并給出 6 種經過實戰檢驗的優化方案。

那晚,大約晚上 11 點,我與 Chaya 在麗江的洱海酒店享受兩人世界的快樂,電商平臺的運維大群突然炸開了鍋。

監控系統發出刺耳的警報:訂單查詢接口響應時間從200ms 飆升到 12 秒,數據庫 CPU 利用率突破 90%。

發現事故根源竟是一個看似平常的查詢——用戶中心的歷史訂單分頁查詢。

這背后隱藏的正是MySQL 深度分頁的典型問題——數據越往后查,速度越讓人抓狂。

其本質是傳統分頁機制在數據洪流下的失效:LIMIT 100000,10這樣的查詢,會讓數據庫像逐頁翻閱千頁文檔的抄寫員,機械地掃描前 10 萬條記錄再丟棄。

當數據量突破千萬級時,這種暴力掃描不僅造成 I/O 資源的巨大浪費,更會導致關鍵業務查詢的鏈式阻塞。

本文將深入拆解深度分頁的技術黑箱,通過電商訂單表等真實場景,揭示 B+樹索引與分頁機制的碰撞奧秘,并給出 6 種經過實戰檢驗的優化方案。

深度分頁

假設電商平臺的訂單表存儲了 2000 萬條記錄,表結構如下,主鍵是 id,(user_id + create_time )聯合索引。

REATE TABLE `orders` (
  `id` int NOT NULL AUTO_INCREMENT, -- id自增
  `user_id` int DEFAULT NULL,
  `amount` decimal(10,2) DEFAULT NULL,
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP, -- 創建時間默認為當前時間
  PRIMARY KEY (`id`),
  KEY `idx_userid_create_time` (`user_id`, `create_time`) -- 創建時間設置為普通索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

我們的分頁語句一般這么寫。

SELECT * FROM orders
WhERE user_id = 'Chaya'
ORDER BY create_time DESC
LIMIT 0, 20;

當用戶查詢第 1000 頁的訂單(每頁 20 條),常見的分頁寫法如下。

SELECT * FROM orders
WhERE user_id = 'Chaya'
ORDER BY create_time DESC
LIMIT 19980, 20;

執行流程解析:

  • 使用聯合索引 idx_userid_create_time讀取 19980 + 20 條數據。
  • 利用索引在內存中排序。
  • 丟棄 19880 條數據,返回剩下的 20 條。

隨著頁碼增加,需要處理的數據量會線性增長。當 offset 達到 10w 時,查詢耗時會顯著增加,達到 100w 時,甚至需要數秒。

游標分頁(Cursor-based Pagination)

適用場景:支持連續分頁(如無限滾動)。

實現原理:基于有序且唯一的字段(如自增主鍵 ID),通過記錄上一頁最后一條記錄的標識(如主鍵 ID),將WHERE條件與索引結合,跳過已查詢數據。

-- 第一頁
SELECT *
FROM orders
WhERE user_id = 'Chaya'
ORDER BY create_time DESC
LIMIT 20;

-- 后續頁(記錄上一頁查詢得到的 id,id=1000)
SELECT id, user_id, amount
FROM orders
WHERE id > 1000 AND user_id = 'Chaya'
ORDER BY create_time DESC
LIMIT 20;

索引樹直接定位到order_id=1000的葉子節點,僅掃描后續 1000 條記錄,避免遍歷前 100 萬行數據。

優勢

  • 完全避免 OFFSET掃描,時間復雜度從 O(N)降為 O(1)
  • 天然支持順序分頁場景(如無限滾動加載)

限制

  • 不支持隨機跳頁(如直接跳轉到第 1000 頁)
  • 需保證排序字段唯一且有序

延遲關聯(Deferred Join)

實現原理通過子查詢先獲取主鍵范圍,再關聯主表獲取完整數據。減少回表次數,利用覆蓋索引優化性能。

SELECT t1.*
FROM orders t1
INNER JOIN (
    SELECT id
    FROM orders
    WhERE user_id = 'Chaya'
		ORDER BY create_time DESC
    LIMIT 1000000, 20
) t2 ON t1.id = t2.id;

優勢

  • 子查詢僅掃描索引樹,避免回表開銷。
  • 主查詢通過主鍵精確匹配,效率極高。
  • 性能提升可達 10 倍以上(實測從 1.2 秒降至 0.05 秒)。

覆蓋索引優化

實現原理:創建包含查詢字段的聯合索引,避免回表操作。例如索引設計為(user_id, id, create_time, amount)。

ALTER TABLE orders ADD INDEX idx_cover (user_id, id, create_time,amount);

SELECT id, user_id, amount, create_time
FROM orders USE INDEX (idx_cover)
WhERE user_id = 'Chaya'
ORDER BY create_time DESC
LIMIT 1000000, 20;

Chaya:訂單很多字段的,我想查看更多訂單細節怎么辦?

這個問題問得好,我們可以設計訂單列表和詳情頁,通過上述方案做訂單列表的分頁查詢;點擊詳情頁的時候,在使用訂單 id 查詢訂單。

分區表

實現原理:將大表按時間或哈希值水平拆分。例如按月分區,每個分區獨立存儲,縮小掃描范圍。

-- 按月份RANGE分區
ALTER TABLE orders PARTITION BY RANGE (YEAR(create_time)*100 + MONTH(create_time)) (
    PARTITION p202501 VALUES LESS THAN (202502),
    PARTITION p202502 VALUES LESS THAN (202503)
);

-- 查詢特定月份數據
SELECT * FROM orders PARTITION (p202501)
WHERE user_id = 'chaya'
ORDER BY create_time DESC
LIMIT 20;

預計算分頁(Precomputed Pages)

實現原理:通過異步任務預生成分頁數據,存儲到 Redis 或物化視圖。適合數據更新頻率低的場景。

實現步驟

  • 定時任務生成熱點頁數據。
  • 存儲到 Redis 有序集合。
ZADD order_pages 0 "page1_data" 1000 "page2_data"
  • 查詢的時候直接獲取緩存數據
-- 偽代碼:獲取第N頁緩存
ZRANGEBYSCORE order_pages (N-1)*1000 N*1000

集成 Elasticsearch

實現原理:利用 ES 的search_after特性,通過游標實現深度分頁。結合數據同步工具保證一致性。

實現流程:canal+kafka 訂閱 MySQL binlog 將數據異構到 elasticsearch。

elasticsearch 保存的數據主要就是我們的查詢條件和訂單 id。

訂單表 → Binlog → Canal → Kafka → Elasticsearch、Hbase

在查詢的時候,通過 Elasticsearch 查詢得到訂單 ID,最后在根據訂單 ID 去 MySQL 查詢。

或者我們可把數據全量同步到 Hbase 中查詢,在 Hbase 中查詢完整的數據。

責任編輯:姜華 來源: 碼哥跳動
相關推薦

2025-06-26 01:55:00

2022-07-12 05:57:00

Mangatoon黑客數據泄露

2019-02-26 13:18:05

MySQL大表優化數據庫

2021-04-16 20:00:54

Docker鏡像攻擊

2022-04-05 13:39:00

mysql數據庫單表

2009-10-19 21:31:59

2022-09-27 08:40:44

慢查詢MySQL定位優化

2025-05-06 00:00:05

MySQLES協同

2025-05-19 00:02:00

數據脫敏加密算法數據庫

2025-01-02 08:21:32

2017-06-26 10:35:58

前端JavaScript繼承方式

2022-09-19 08:41:02

數據查詢分離

2022-07-05 10:50:31

數據庫查詢實戰

2020-12-30 18:58:03

數字人民幣數字貨幣區塊鏈

2011-07-28 16:39:03

MySQL數據庫修改MySQL密碼

2023-09-27 08:21:00

查詢分離數據API

2024-05-28 08:47:52

2011-03-31 14:53:13

數據中心節能

2010-06-13 11:28:39

UML序列圖

2010-10-08 11:13:22

MySQL修改密碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产99精品 | 中文字幕 国产 | 毛片软件 | 欧美久久免费观看 | 成人av片在线观看 | 久久精品成人 | 久久亚洲一区二区三 | 欧美激情精品久久久久 | 欧美一区二区大片 | 99精品视频一区二区三区 | 天天噜天天干 | 国产午夜一级 | 观看毛片| 欧美日韩综合视频 | 欧美精品一区二区三区四区五区 | 午夜亚洲 | 欧美成人一区二免费视频软件 | 欧美在线天堂 | 久草精品视频 | 99精品国产一区二区三区 | 久久久久国产精品一区二区 | 免费毛片网 | 亚洲日日夜夜 | 全免一级毛片 | 综合九九| 亚洲精品一区二区三区蜜桃久 | 日本污视频| 国产韩国精品一区二区三区 | 一区二区日本 | 亚洲国产一区二区三区 | 视频三区 | av一级久久 | 欧美不卡一区二区 | 国产免费一区 | 91久久精品一区二区二区 | 日韩一区二区在线观看 | 精品亚洲一区二区三区四区五区 | 久久高清| 成人国产一区二区三区精品麻豆 | 精品一级 | 中文字幕日韩一区 |