優化分頁查詢

2021-08-11 00:00:46 字數 3969 閱讀 2758

我們一般使用分頁都是使用limit來完成的,如果資料量小的話還可以,但是當資料量非常大的時候,不建立索引,通過全表查詢,將會非常耗時,效能將受到很大的影響。

第一種優化方式

在索引上完成排序分頁的操作,最後根據主鍵關聯回原表查詢所需要的其他列內容

例:我想對我之前的分頁進行優化,沒有優化前的sql語句

select news_id, news_title, news_content

from news

limit #, #

對其進行優化:

1)我首先在news_title上建立了乙個索引

2)修改sql語句

修改以後:

select a.news_id, a.news_title, a.news_content

from news a inner join

(select news_id from news order by news_title

limit #, #

) b on a.news_id = b.news_id

感覺自己是為了強行使用索引優化而改的,因為做了測試效能並沒有提公升。也有可能是自己資料庫的資料量太少了,只有100行

第一種索引優化是利用了二級索引的特點,二級索引的葉子結點存放的是自定義索引+主鍵(這裡為news_title+news_id)先通過索引排序分頁,在索引上進行排序是很快的,其實根本就不用排了,索引是順序儲存的,然後再利用主鍵進行表關聯

通過explain檢視執**況

優化前:select * from news order by news_title limit 10,5

mysql> explain select * from news order by news_title limit 10,5 \g

*************************** 1. row ***************************

id: 1

select_type: ******

table: news

partitions: null

type: all

possible_keys: null

key: null

key_len: null

ref: null

rows: 93

filtered: 100.00

extra: using filesort

1 row in set, 1 warning (0.00 sec)

優化後:select a.* from news a inner join (select news_id from news order by news_title limit 20,5) b using(news_id)、

mysql> explain select a.* from news a inner join (select news_id from news order by news_title limit 10,5) b using(news_id)\g

*************************** 1. row ***************************

id: 1

select_type: primary

table: partitions: null

type: all

possible_keys: null

key: null

key_len: null

ref: null

rows: 15

filtered: 100.00

extra: null

*************************** 2. row ***************************

id: 1

select_type: primary

table: a

partitions: null

type: eq_ref

possible_keys: primary

key: primary

key_len: 4

ref: b.news_id

rows: 1

filtered: 100.00

extra: null

*************************** 3. row ***************************

id: 2

select_type: derived

table: news

partitions: null

type: index

possible_keys: null

key: news_title

key_len: 767

ref: null

rows: 15

filtered: 100.00

extra: using index

3 rows in set, 1 warning (0.00 sec)

mysql> explain select * from news limit 10,5\g

*************************** 1. row ***************************

id: 1

select_type: ******

table: news

partitions: null

type: all

possible_keys: null

key: null

key_len: null

ref: null

rows: 93

filtered: 100.00

extra: null

1 row in set, 1 warning (0.00 sec)

優化前通過檔案排序,檔案排序是非常浪費時間和空間的,並且其是通過全表進行排序的,掃瞄的資料量非常多

優化後,使用索引排序,並且可以看到雖然子查詢表中是全表掃瞄,但是也做到了掃瞄盡可能的行

第二種優化方式

把limit查詢轉化成某個位置的查詢

在查詢的過程中需要記錄上一次查詢到的地方

在繼續對上面的例子進行優化

select news_id, news_title, news_content

from news where news_id > # order by news_id limit #

這種優化方式只適合排序字段不會出現重複值的特定場景,如果排序字段出現大量重複值,會造成分頁結果的丟失。

如果第二種方式可以使用的話,則第二種優化的方式比第一種的效率更高,通過explain,第二種type為range,而第一種type為index。range的效能要比index好。

mysql> explain select * from tt where id>5 order by id limit 5\g

*************************** 1. row ***************************

id: 1

select_type: ******

table: tt

partitions: null

type: range

possible_keys: primary

key: primary

key_len: 4

ref: null

rows: 15

filtered: 100.00

extra: using where

1 row in set, 1 warning (0.00 sec)

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如何優化分頁查詢

mysql如何優化分頁查詢一般分頁查詢是建立覆蓋索引能夠比較好的提公升效能。第一種優化思路 在索引上完成分頁操作,最後根據主鍵關聯回原表查詢所需要的其他列內容 未優化之前的sql,這個相當於是全表掃瞄 select film id,description from film order by tit...

oracle資料庫優化 分頁查詢優化

在oracle12c以上出現fetch命令進行分頁查詢問題 sql select from 2 3 select a.rownum rn 4 from select from tab test 1 a 5 6 where rn between 21 and 40 sql分析 select from ...