mysql大資料量分頁查詢優化總結

2022-09-14 17:00:17 字數 2954 閱讀 8255

mysql的分頁查詢十分簡單,但是當資料量大的時候一般的分頁就吃不消了。

傳統分頁查詢:select c1,c2,cn… from table limit n,m

mysql的limit工作原理就是先讀取前面n條記錄,然後拋棄前n條,讀後面m條想要的,所以n越大,偏移量越大,效能就越差。

1)limit語句的查詢時間與起始記錄的位置成正比

2)mysql的limit語句是很方便,但是對記錄很多的表並不適合直接使用。

1、盡量給出查詢的大致範圍

利用表的覆蓋索引來加速分頁查詢

我們都知道,利用了索引查詢的語句中如果只包含了那個索引列(覆蓋索引:索引的資料覆蓋了需要查詢的所有資料),那麼這種情況會查詢很快。

因為利用索引查詢有優化演算法,且資料就在查詢索引上面,不用再去找相關的資料位址了,這樣節省了很多時間。另外mysql中也有相關的索引快取,在併發高的時候利用快取就效果更好了。

在我們的例子中,我們知道id欄位是主鍵,自然就包含了預設的主鍵索引。現在讓我們看看利用覆蓋索引的查詢效果如何:

之前,我們取最後一頁記錄的時間

select * from product limit 866613, 20   37.44秒
這次我們查詢最後一頁的資料(利用覆蓋索引,只包含id列),如下:

select id from product limit 866613, 20 0.2秒
相對於查詢了所有列的37.44秒,提公升了大概100多倍的速度

那麼如果我們也要查詢所有列,有兩種方法,一種是id>=的形式,另一種就是利用join,看下實際情況:

select * from product where id > =(select id from product limit 866613, 1) limit 20

查詢時間為0.2秒,簡直是乙個質的飛躍

另一種寫法

select * from product a join (select id from product limit 866613, 20) b on a.id = b.id
*統配符號在實際查詢的中不應該使用,應該指明相應的屬性,效率更好

其實兩者用的都是乙個原理,所以效果也差不多.

select c1,c2,cn... from table where id>=20000 limit 10;
2、子查詢法(在方法1基礎上改進的)

select c1,c2,cn... from table where id>=

( select id from table limit 20000,1

)limit 10;

3、 第一步用用程式讀取出id,然後再用in方法讀取所需記錄

程式讀id:

select id from table limit 20000, 10;

select c1, c2, cn .. . from table where id in (id1, id2, idn.. .)

4.高效能mysql一書中提到的唯讀索引方法(sql語句相比前三種複雜)

一般表中經常作為條件查詢的列都會建立索引,例如如下查詢

sql**  優化前

select id, content  from tb_chat order by create_time desc limit 24000, 20;
sql**   優化後

select id, content from tb_chat   

inner join (

select id from tb_chat

order by create_time limit 24000, 20

) as page using(id);

這樣當前查詢頁的內容就只會在索引中進行,當得到當前頁的id再統一通過乙個inner join得到最終要得到的資料詳情,避免了對大量資料詳情進行操作的消耗。當然join操作也可以通過子查詢實現,不過書中介紹5.6之前版本的mysql相比子查詢還是優先使用join。

對上乙個sql繼續優化改進,當有查詢條件分頁時,一定要確保有資料是在limit後面的條件裡,正常有輸入條件檢索查詢應該是limit 0, 10   我寫的是limit 15000,20只是為了測試,因為符合該條件的資料只有1萬5千多個,不然超出這個數就查不到資料了,切記。

select id, content,c.z_type from tb_chat c

inner join (

select id,z_type from tb_chat where z_type='1'

order by create_time limit 15000, 20

) as page using(id);

等同於:

select c.id, c.content,c.z_type from tb_chat c

inner join (

select id,z_type from tb_chat where z_type='1'

order by create_time limit 15000, 20

) as p on c.id=p.id;

個人覺得此方法更為通用,而且經過我的測試,發現表中總資料只有3萬條資料時兩個sql語句的執行時間竟然相差4倍,優化前的sql執行需要120ms,而優化後的sql需要30ms。

參考:

mysql大資料量分頁查詢優化

參考文章 mysql的分頁查詢十分簡單,但是當資料量大的時候一般的分頁就吃不消了。傳統分頁查詢 select c1,c2,cn from table limit n,m mysql的limit工作原理就是先讀取前面n條記錄,然後拋棄前n條,讀後面m條想要的,所以n越大,偏移量越大,效能就越差。1 盡...

mysql大資料量分頁查詢優化

參考文章 mysql的分頁查詢十分簡單,但是當資料量大的時候一般的分頁就吃不消了。傳統分頁查詢 select c1,c2,cn from table limit n,m mysql的limit工作原理就是先讀取前面n條記錄,然後拋棄前n條,讀後面m條想要的,所以n越大,偏移量越大,效能就越差。1 盡...

Mysql大資料量分頁優化

假設有乙個千萬量級的表,取1到10條資料 select from table limit 0,10 select from table limit 1000,10 這兩條語句查詢時間應該在毫秒級完成 select from table limit 3000000,10 你可能沒想到,這條語句執行之間...