淺談為什么MySQL不推薦使用子查詢和join
做分頁查詢:
1.對于mysql,不推薦使用子查詢和join是因?yàn)楸旧韏oin的效率就是硬傷,一旦數(shù)據(jù)量很大效率就很難保證,強(qiáng)烈推薦分別根據(jù)索引單表取數(shù)據(jù),然后在程序里面做join,merge數(shù)據(jù)。
2.子查詢就更別用了,效率太差,執(zhí)行子查詢時(shí),MYSQL需要?jiǎng)?chuàng)建臨時(shí)表,查詢完畢后再刪除這些臨時(shí)表,所以,子查詢的速度會受到一定的影響,這里多了一個(gè)創(chuàng)建和銷毀臨時(shí)表的過程。
3.如果是JOIN的話,它是走嵌套查詢的。小表驅(qū)動(dòng)大表,且通過索引字段進(jìn)行關(guān)聯(lián)。如果表記錄比較少的話,還是OK的。大的話業(yè)務(wù)邏輯中可以控制處理。
4.數(shù)據(jù)庫是最底層的,瓶頸往往是數(shù)據(jù)庫。建議數(shù)據(jù)庫只是作為數(shù)據(jù)store的工具,而不要添加業(yè)務(wù)上去。
一、應(yīng)用層關(guān)聯(lián)的優(yōu)勢
讓緩存的效率更高。許多應(yīng)用程序可以方便地緩存單表查詢對應(yīng)的結(jié)果對象。如果關(guān)聯(lián)中的某個(gè)表發(fā)生了變化,那么就無法使用查詢緩存了,而拆分后,如果某個(gè)表很少改變,那么基于該表的查詢就可以重復(fù)利用查詢緩存結(jié)果了。
將查詢分解后,執(zhí)行單個(gè)查詢可以減少鎖的競爭。
在應(yīng)用層做關(guān)聯(lián),可以更容易對數(shù)據(jù)庫進(jìn)行拆分,更容易做到高性能和可擴(kuò)展。
查詢本身效率也可能會有所提升。查詢id集的時(shí)候,使用IN()代替關(guān)聯(lián)查詢,可以讓MySQL按照ID順序進(jìn)行查詢,這可能比隨機(jī)的關(guān)聯(lián)要更高效。
可以減少冗余記錄的查詢。在應(yīng)用層做關(guān)聯(lián)查詢,意味著對于某條記錄應(yīng)用只需要查詢一次,而在數(shù)據(jù)庫中做關(guān)聯(lián)查詢,則可能需
要重復(fù)地訪問一部分?jǐn)?shù)據(jù)。從這點(diǎn)看,這樣的重構(gòu)還可能會減少網(wǎng)絡(luò)和內(nèi)存的消艷。
更進(jìn)一步,這樣做相當(dāng)于在應(yīng)用中實(shí)現(xiàn)了哈希關(guān)聯(lián),而不是使用MySQL的嵌套循環(huán)關(guān)聯(lián)。某些場景哈希關(guān)聯(lián)的效率要高很多。
二、應(yīng)用層關(guān)聯(lián)的使用場景
當(dāng)應(yīng)用能夠方便地緩存單個(gè)查詢的結(jié)果的時(shí)候
當(dāng)可以將數(shù)據(jù)分布到不同的MySQL服務(wù)器上的時(shí)候
當(dāng)能夠使用IN()的方式代替關(guān)聯(lián)查詢的時(shí)候
并發(fā)場景多,DB查詢頻繁,需要分庫分表
三、不推薦使用join的原因
1.DB承擔(dān)的業(yè)務(wù)壓力大,能減少負(fù)擔(dān)就減少。當(dāng)表處于百萬級別后,join導(dǎo)致性能下降;
2.分布式的分庫分表。這種時(shí)候是不建議跨庫join的。目前mysql的分布式中間件,跨庫join表現(xiàn)不良。
3.修改表的schema,單表查詢的修改比較容易,join寫的sql語句要修改,不容易發(fā)現(xiàn),成本比較大,當(dāng)系統(tǒng)比較大時(shí),不好維護(hù)。
四、不使用join的解決方案
在業(yè)務(wù)層,單表查詢出數(shù)據(jù)后,作為條件給下一個(gè)單表查詢。也就是子查詢。會擔(dān)心子查詢出來的結(jié)果集太多。mysql對in的數(shù)量沒有限制,但是mysql限制整條sql語句的大小。通過調(diào)整參數(shù)max_allowed_packet ,可以修改一條sql的最大值。建議在業(yè)務(wù)上做好處理,限制一次查詢出來的結(jié)果集是能接受的。
五、join查詢的優(yōu)勢
關(guān)聯(lián)查詢的好處是可以做分頁,可以用副表的字段做查詢條件,在查詢的時(shí)候,將副表匹配到的字段作為結(jié)果集,用主表去in它。但是問題來了,如果匹配到的數(shù)據(jù)量太大就不行了,也會導(dǎo)致返回的分頁記錄跟實(shí)際的不一樣,解決的方法可以交給前端,一次性查詢,讓前端分批顯示就可以了,這種解決方案的前提是數(shù)據(jù)量不太,因?yàn)閟ql本身長度有限。
到此這篇關(guān)于淺談為什么MySQL不推薦使用子查詢和join的文章就介紹到這了,更多相關(guān)MySQL 子查詢和join內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql 導(dǎo)入導(dǎo)出數(shù)據(jù)庫以及函數(shù)、存儲過程的介紹
本篇文章是對mysql中的導(dǎo)入導(dǎo)出數(shù)據(jù)庫命令以及函數(shù)、存儲過程進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-07-07在MySQL數(shù)據(jù)庫中復(fù)位根用戶的密碼的方法
2007-12-12MySQL數(shù)據(jù)庫的實(shí)時(shí)備份知識點(diǎn)詳解
本篇文章給大家分享了關(guān)于MySQL數(shù)據(jù)庫的實(shí)時(shí)備份知識點(diǎn)內(nèi)容,有需要的朋友們可以參考下。2018-08-08解決MySQL8.0安裝第一次登陸修改密碼時(shí)出現(xiàn)的問題
這篇文章主要介紹了解決MySQL8.0安裝第一次登陸修改密碼時(shí)出現(xiàn)的問題,在文章開頭給大家介紹了mysql 8.0.16 初次登錄修改密碼的方法,需要的朋友可以參考下2019-06-06mysql數(shù)據(jù)存儲過程參數(shù)實(shí)例詳解
這篇文章主要介紹了mysql數(shù)據(jù)存儲過程參數(shù)實(shí)例詳解,小編覺得挺不錯(cuò)的,這里分享給大家,供需要的朋友參考。2017-10-10mysql Community Server 5.7.19安裝指南(詳細(xì))
這篇文章主要介紹了mysql Community Server 5.7.19安裝指南(詳細(xì)),需要的朋友可以參考下2017-10-10