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

MySQL 的分頁查詢優化策略解析

數據庫 MySQL
本文通過一張大表結合一個分頁查詢的場景為讀者演示的大表分頁查詢的技巧,整體來說,針對大表查詢時,我們的SQL優化要遵循以下幾點。

千萬級別的MySQL單表查詢算是近幾年面試時碰到的一道比較棘手的問題,因為很多開發沒有這方面的經驗,所以最終回答都不是很好,所以筆者就以MySQL8作為實驗數據庫為讀者演示一下筆者日常的處理思路和技巧。

百萬級別數據查詢實踐

前置準備

為了方便演示筆者,這里拿出一張曾經作為批量插入的數據表,該表差不多有1000w左右的數據:

CREATE TABLE `batch_insert_test` (
  `id` int NOT NULL AUTO_INCREMENT,
  `fileid_1` varchar(100) DEFAULT NULL,
  `fileid_2` varchar(100) DEFAULT NULL,
  `fileid_3` varchar(100) DEFAULT NULL,
  `fileid_4` varchar(100) DEFAULT NULL,
  `fileid_5` varchar(100) DEFAULT NULL,
  `fileid_6` varchar(100) DEFAULT NULL,
  `fileid_7` varchar(100) DEFAULT NULL,
  `fileid_8` varchar(100) DEFAULT NULL,
  `fileid_9` varchar(100) DEFAULT NULL,
  `fileid_10` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25414 DEFAULT CHARSET=utf8mb3 COMMENT='測試批量插入,一行數據1k左右';

如何limit

按照分頁查詢公式,查詢第N頁的sql就是limit (page-1)*size, size,所以筆者對如下幾個分頁查詢進行實驗,不難看出,隨著分頁深度的增加,查詢也變得十分耗時:

select * from batch_insert_test bit2 limit 10,10;
select * from batch_insert_test bit2 limit 100,10;
select * from batch_insert_test bit2 limit 1000,10;
select * from batch_insert_test bit2 limit 10000,10;
select * from batch_insert_test bit2 limit 100000,10;
select * from batch_insert_test bit2 limit 1000000,10;
select * from batch_insert_test bit2 limit 5000000,10;

查看第500w頁的數據10條,花費了將近10s:

select * from batch_insert_test limit 5000000,10;

因為查詢時沒有使用任何索引,所以查詢時直接進行完整的table scan即針對整顆聚簇索引樹的非空data域進行掃描檢索:

查看其執行計劃,可以發現本次查詢走了全表掃描,性能表現非常差勁:

id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows   |filtered|Extra|
--+-----------+-----+----------+----+-------------+---+-------+---+-------+--------+-----+
 1|SIMPLE     |batch_insert_test |          |ALL |             |   |       |   |9004073|   100.0|     |

所以我們需要對這些SQL進行改造,因為筆者這張表是以id作為主鍵的,所以我們可以很好的利用這一點,通過定位當前頁的第一個id,然后通過這個id篩選對應頁的數據:

對應SQL如下所示,經過筆者的實驗耗時大約在500ms左右:

select
 *
from
 batch_insert_test 
where
 id >=(select id from batch_insert_test bit2 limit 5000000,1)
 limit 10;

查看這條sql的執行計劃可以發現,這條sql是直接通過索引直接定位id,避免走向葉子節點直接返回,再通過走索引的方式進行范圍查詢性能提升了不少。

id|select_type|table|partitions|type |possible_keys|key    |key_len|ref|rows |filtered|Extra                         |
--+-----------+-----+----------+-----+-------------+-------+-------+---+-----+--------+------------------------------+
 1|PRIMARY    |     |          |     |             |       |       |   |     |        |no matching row in const table|
 2|SUBQUERY   |bit2 |          |index|             |PRIMARY|4      |   |38677|   100.0|Using index                   |

當然,我們也可以通過子查詢的方式先定位到索引區間,然后再和查詢的表進行關聯完成檢索,性能表現也差不多,這里不多做贅述了:

select
 b1.*
from
 batch_insert_test b1
inner join (
 select
  id
 from
  batch_insert_test
 limit 5000000,
 10) as b2 on
 b1.id = b2.id;

limit多少

接下來就是limit數據量的選擇了,有些讀者可能為了方便直接在業務上進行改造,一次性查詢大幾十萬數據給用戶。 可以看到隨著數據量的增加,查詢耗時主鍵增大,所以讀者在進行這方面考慮的時候務必要結合壓測,根據自己業務上所能容忍的延遲涉及最大的pageSize,以筆者為例大約10w條以內的數據查詢性能差異是不大的(上下相差200ms左右):

select * from batch_insert_test bit2 limit 1000000,10;
select * from batch_insert_test bit2 limit 1000000,100;
select * from batch_insert_test bit2 limit 1000000,1000;
select * from batch_insert_test bit2 limit 1000000,10000;
select * from batch_insert_test bit2 limit 1000000,100000;
select * from batch_insert_test bit2 limit 1000000,1000000;
select * from batch_insert_test bit2 limit 1000000,10000000;

其他注意事項

還有一點細節上的優化,MySQL的基本單位是頁,所以每次查詢都是以頁為單位進行查詢,所以高效的查詢也要求我們用盡可能少的塊查到存儲盡可能多的數據,所以查詢時我們建議沒有用到的列就不要查詢來了。

以筆者為例,只需用到3個字段,則直接將*改為了id,fileid_1 ,fileid_4

select
 id,fileid_1 ,fileid_4 
from
 batch_insert_test bit2
where
 id >(select id from batch_insert_test bit2 limit 5000000,1)
 limit 10;

小結

來簡單小結一下,本文通過一張大表結合一個分頁查詢的場景為讀者演示的大表分頁查詢的技巧,整體來說,針對大表查詢時,我們的SQL優化要遵循以下幾點:

  • 盡可能利用索引,確保用最小的開銷得到索引。
  • 結合業務場景和服務器性能壓測出最合適的limit數據量。
  • 盡量不要查詢沒必要的列。
責任編輯:趙寧寧 來源: 寫代碼的SharkChili
相關推薦

2010-11-25 14:21:16

MySQL查詢分頁

2025-05-20 08:05:00

分頁查詢MySQL索引

2017-07-25 15:35:07

MysqlMysql優化LIMIT分頁

2019-09-11 10:40:49

MySQL大分頁查詢數據庫

2019-11-15 10:01:07

MySQL數據庫數據

2009-06-11 14:40:59

Hibernate分頁Hibernate查詢

2024-05-23 10:19:57

2009-05-15 10:11:55

數據庫查詢查詢性能分頁瀏覽

2018-09-06 16:46:33

數據庫MySQL分頁查詢

2023-02-26 23:43:43

MySQL數據庫分頁查詢

2010-06-12 15:31:04

MySQL查詢優化

2024-12-05 09:06:58

2023-10-12 19:41:55

2025-04-15 08:30:00

2025-01-15 08:05:06

MySQLLEFT JOIN數據庫

2010-06-10 12:37:27

MySQL分頁查詢

2023-09-01 15:34:34

數據庫開發

2010-10-14 16:27:56

MySQL隨機查詢

2011-07-11 15:28:19

MySQL索引優化

2010-06-11 14:41:20

MySQL分頁查詢
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品色欧美aⅴ一区二区 | 看羞羞视频 | 色男人的天堂 | 亚洲成人自拍 | 日韩国产精品一区二区三区 | 欧美午夜影院 | 99这里只有精品视频 | 日韩视频在线观看中文字幕 | 欧美一级在线免费观看 | 欧美亚洲国产一区 | 91久久精品日日躁夜夜躁国产 | 毛片免费在线 | 国户精品久久久久久久久久久不卡 | 欧美中文一区 | 欧美成人免费在线视频 | 可以在线观看av的网站 | 亚洲精品aⅴ | 国产一区久久久 | 成人在线不卡 | 高清视频一区二区三区 | 91久久精品国产91久久 | 国产高清免费 | 国产色99精品9i | 成人精品在线观看 | 亚洲成人av一区二区 | 欧美久久一区二区 | 欧美1区 | 国产在线精品一区 | 网站黄色在线免费观看 | 亚洲精品久久久久中文字幕欢迎你 | 中文字幕亚洲一区二区三区 | 国产成人一区二区三区 | 欧美日韩精品影院 | 日韩av中文 | 久久久精品影院 | 亚洲先锋影音 | 国产午夜精品一区二区三区嫩草 | 亚洲国产网址 | 久久久久成人精品免费播放动漫 | 一区二区三区视频在线观看 | 国产激情精品一区二区三区 |