linux mysql 不稳定_linux,mysql:今天写出一个十分弱智的bug!
今天寫出一個(gè)十分弱智的bug,記錄一下,提醒自己以后別這種犯錯(cuò),不怕丟人哈~
在寫一個(gè)分頁(yè)查詢記錄的sql時(shí),要根據(jù)添加的時(shí)間逆序分頁(yè)輸出,之前的寫法是醬紫:
select
record.a, y.c from ( select
a,b from x
order by timestamp desc
limit 0,10 ) record
left join y
on record.b = y.d;
因?yàn)橐恍┬碌男枨?#xff0c;要在后面加一些where條件,limit操作不能在嵌套查詢里面加了,于是乎把limit 0,10提出來(lái)放到最外面,結(jié)果order by還留在里面。
我當(dāng)時(shí)想嵌套查詢出來(lái)的record表已經(jīng)按timestamp字段逆序排列了,再left另一張表,最終再limit出來(lái)的結(jié)果應(yīng)該也是逆序的,但結(jié)果卻很打臉,是正序的。
首先控制變量,代碼回滾到之前,把后來(lái)加的各種邏輯都去掉,還原到上述sql,只把limit 0,10移到最后,發(fā)現(xiàn)timestamp是正序的,那么問(wèn)題應(yīng)該就出在這里了,與后來(lái)加的其他邏輯沒(méi)有關(guān)系。
那么再試一下刪掉limit操作,結(jié)果timestamp是無(wú)序的!
這不可能啊,于是認(rèn)真看了下數(shù)據(jù),發(fā)現(xiàn)一些規(guī)律,可能是按y表的自增id或created_at時(shí)間字段排序的(因?yàn)檫@兩個(gè)字段是索引字段),那么到這里,我們至少可以得到一個(gè)簡(jiǎn)單的結(jié)論,就是聯(lián)表查詢結(jié)果,不是按照嵌套查詢中的order by排序的,現(xiàn)在正向一看,確實(shí)不可能按這個(gè)排序,因?yàn)槔ㄌ?hào)里面的邏輯對(duì)括號(hào)外是不可見(jiàn)的。
還有個(gè)問(wèn)題,上述去掉limit后,最終不是按left join主表的順序輸出,按照我們常理想象,mysql是循環(huán)主表的記錄去關(guān)聯(lián)另一張表,那么輸出的順序應(yīng)該還是主表的順序啊,但結(jié)果卻是按另一張表的字段排序的,這又是為什么呢?圖解 5 種 Join 連接這篇推薦大家看下。
去官方手冊(cè)中找找線索,發(fā)現(xiàn)order by模塊中有這么一句話。
再去limit模塊中看一下
從以上兩個(gè)截圖中,我們可以發(fā)現(xiàn)一些端倪,limit操作會(huì)對(duì)查詢有一些優(yōu)化,查詢到指定條數(shù)的數(shù)據(jù),就可以提前結(jié)束了,比如我們本文中的left操作,拿到10條結(jié)果就結(jié)束查詢線程,返回客戶端。
我猜測(cè),如果沒(méi)有l(wèi)imit操作,反正全部都要join,可能mysql會(huì)對(duì)循環(huán)邏輯做一些優(yōu)化,不一定要按主表來(lái)循環(huán),思想類似于java編譯中的重排序,也對(duì)應(yīng)了上面截圖中的那句話。
采用最簡(jiǎn)單、最粗暴的方式,直接把order by 和 limit操作放到最外面就ok啦,其實(shí)效率上并沒(méi)有什么降低,只要索引建的合理即可。
總結(jié)
以上是生活随笔為你收集整理的linux mysql 不稳定_linux,mysql:今天写出一个十分弱智的bug!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql减少锁等待_降低锁竞争 减少M
- 下一篇: mysql isreg_`Innodb`