MySQL 利用延遲關聯優化分頁查詢

2021-09-21 01:21:04 字數 930 閱讀 9425

通常會有一些起點巨大的分頁查詢,效率低下,例如:

select * from tab 

where create_date>'2018-12-20 13:20:10' and create_date<'2019-05-01 14:00:00'

order by id

limit 328000,10;

假設tab是乙個資料量非常大的表,且滿足條件create_date>'2018-12-20 13:20:10' and create_date<'2019-05-01 14:00:00'的資料量在百萬以上,如果create_date列上有乙個二級索引,那麼需要在二級索引上每遍歷乙個符合條件的索引行,都需要回表一次。取得所有符合條件的資料行後,再根據id進行排序,需要filesort操作。

所以即使在create_date列上存在索引,對於上述sql由於回表的開銷,最終優化器一般都會選擇全表掃瞄。而全表掃瞄的代價就是查詢效率非常慢。

針對這一類分頁查詢,可以利用延遲關聯的手法進行優化,改寫如下:

select * from 

tab a,

(select id from tab where create_date>'2018-12-20 13:20:10' and create_date<'2019-05-01 14:00:00' order by id limit 328000,10) b

where a.id=b.id;

改寫後快的原因在於,子查詢b可以通過create_date索引走覆蓋索引,這個覆蓋索引一定比tab錶小很多。另外,在上述sql以外的情況,如果能利用覆蓋索引同時避免排序,那麼就能在獲取足夠數量的資料時及時停止掃瞄。子查詢b查出符合條件的主鍵id,然後與a關聯,這時b得到的id通過a的id主鍵索引,能夠唯一確定一行資料,高效地從tab獲取資料。

mysql優化 優化分頁查詢

create table goods id bigint 20 unsigned not null auto increment,name varchar 10 default null,price double default null,create time datetime default n...

Mysql優化之延遲關聯

有如下sql select from user where name abc order by age limit 10000,10。這個語句同時使用了order和limit,如果沒有索引的話會很慢。那麼可以加上如下索引 name,age 但是加索引之後可能還是很慢,因為這個索引不是覆蓋索引,查詢欄...

利用延遲關聯或者子查詢優化超多分頁場景

推薦 利用延遲關聯或者子查詢優化超多分頁場景。說明 mysql 並不是跳過 offset 行,而是取 offset n 行,然後返回放棄前 offset 行,返回 n 行,那當 offset 特別大的時候,效率就非常的低下,要麼控制返回的總頁數,要麼對超過 特定閾值的頁數進行 sql 改寫。正例 先...