記一次Mysql大資料分頁優化問題

2021-08-16 08:01:43 字數 1720 閱讀 4730

一般分頁用的是limit

當資料量比較大的時候比如select * from u_user limit 10000000,10

這樣查詢就會奇慢無比,因為mysql會查詢前面 一百萬+10條資料之後 再丟棄前面一百萬條資料返回最後10條資料;

怎麼優化呢? 優化方式很多,一般的方式是

select * from u_user where id >= (select id from u_user limit 10000000,1) limit 10

這樣優化沒有錯,速度也大幅度提高;

1.但是後來發現了這樣乙個問題,優化後和優化前的資料不一致啊?

後來發現select id from u_user limit 10000000,1每次的結果也不一致;

正式因為這個不一致導致了上面優化的查詢不一致。為什麼會不一致呢?

今天遇到乙個問題,有乙個 select 語句沒有加 「order by」,返回的資料是不確定的。

這種問題碰到不止幾次了。追根尋底, select 語句如果不加 「order by」, mysql會怎麼排序呢?

在網上搜了一下,在mysql論壇發現了這篇文章。

簡單翻譯一下

* 不能依賴 mysql 的預設排序

* 如果你想排序,總是加上 order by

* group by 強加了 order by (這與標準語法衝突,如果要避免,請使用 order by null)這裡我有疑問,

到底強加了何種 order by

對於 myisam 表

mysql select 預設排序是按照物理儲存順序顯示的。(不進行額外排序).

也就是說

select * from tbl – 會產生「表掃瞄」。如果表沒有刪除、替換、更新操作,記錄會顯示為插入的順序。

innodb 表

同樣的情況,會按主鍵的順序排列。再次強調,這只是潛規則(artifact of the underlying implementation:怎麼翻譯?),

不靠譜的。

我的理解與推測:

「select」 不加 「order by」時, mysql 會嘗試以盡可能快的方法(mysql 實際的方法不見得快)返回資料。

由於訪問主鍵、索引大多數情況會快一些(在cache裡)所以返回的資料有可能以主鍵、索引的順序輸出,

這裡並不會真的進行排序,主要是由於主鍵、索引本身就是排序放到記憶體的,所以連續輸出時可能是某種序列。

在一些情況下消耗硬碟尋道時間最短的資料會先返回。

如果只查詢單個表,在特殊的情況下是有規律的。

最後總結

「order by 是要加的」

如果誰想更深一步了解,需要看看 mysql 的源**了。

如上,是關鍵,因為mysql預設排序的不確定性,所以每次返回的都不一樣

解決辦法:加上order by

select * from u_user where id >= (select id from u_user order by id  limit 10000000,1) limit 10;

然後我又發現了乙個問題

2.為啥select id from u_user order by id  limit 10000000,1返回的順序不能保證

但是貌似select * from u_user order by id  limit 10000000,1 每次返回都是一致的呢???

有人告知麼?

記一次MySQL索引優化

兩張表是主 check drawings 從 check drawings img 關係。check drawings,主表資料 3591條。select count from check drawings 3591 check drawings img,從表資料107203條,資料量並不大,從表通...

資料庫優化 記一次Mysql的優化經歷

1.建立乙個課程表 create table course c id int primary key,name varchar 10 2.建立乙個學生表create table student s id int primary key,name varchar 10 3.建立乙個課程學生表creat...

記一次SQL優化

問題發生在關聯主表a 4w資料量 和副表b 4w資料量 關聯欄位都是openid 當時用的是 left join 直接跑sql,卡死 伺服器也是差 優化1 改left join 為join,兩者區別就是left join查詢時已主表為依據,該是幾條就幾條 就算副表沒有關聯的資料 join如果副表沒有...