MySql數(shù)據(jù)庫單表查詢與多表連接查詢效率對(duì)比
這段時(shí)間在做項(xiàng)目的過程中,遇到一個(gè)模塊,數(shù)據(jù)之間的聯(lián)系很復(fù)雜,在建表的時(shí)候就很糾結(jié),到底該怎么去處理這些復(fù)雜的數(shù)據(jù)呢,是單表查詢,然后在業(yè)務(wù)層去處理數(shù)據(jù)間的關(guān)系,還是直接通過多表連接查詢來處理數(shù)據(jù)關(guān)系呢?
通過查閱資料和閱讀博客,有以下兩個(gè)回答:
一、《高性能mysql》中的回答
很多高性能的應(yīng)用都會(huì)對(duì)關(guān)聯(lián)查詢進(jìn)行分解。簡(jiǎn)單地,可以對(duì)每個(gè)表進(jìn)行一次單表查詢,然后將結(jié)果在應(yīng)用程序中進(jìn)行關(guān)聯(lián)。例如,下面這個(gè)查詢:
select * from tag join tag_post on tag_post.tag_id=tag.id join post on tag_post.post_id=post.id where tag.tag='mysql';
可以分解成下面這些查詢來代替:
Select * from tag where tag='mysql'; Select * from tag_post where tag_id=1234; Select * from post where id in(123,456,567,9989,8909);
到底為什么要這樣做?
咋一看,這樣做并沒有什么好處,原本一條查詢,這里卻變成了多條查詢,返回結(jié)果又是一模一樣。
事實(shí)上,用分解關(guān)聯(lián)查詢的方式重構(gòu)查詢具有如下優(yōu)勢(shì):(高并發(fā)、高性能的應(yīng)用中,一般建議使用單表查詢)
1. 讓緩存的效率更高。許多應(yīng)用程序可以方便地緩存單表查詢對(duì)應(yīng)的結(jié)果對(duì)象。另外對(duì)于MySQL的查詢緩存來說,如果關(guān)聯(lián)中的某個(gè)表發(fā)生了變化,那么就無法使用查詢緩存了,而拆分后,如果某個(gè)表很少改變,那么基于該表的查詢就可以重復(fù)利用查詢緩存結(jié)果了。
2. 將查詢分解后,執(zhí)行單個(gè)查詢可以減少鎖的競(jìng)爭(zhēng)。
3. 在應(yīng)用層做關(guān)聯(lián),可以更容易對(duì)數(shù)據(jù)庫進(jìn)行拆分,更容易做到高性能和可擴(kuò)展。
4. 查詢本身效率也可能會(huì)有所提升。
5. 可以減少冗余記錄的查詢。
6. 更進(jìn)一步,這樣做相當(dāng)于在應(yīng)用中實(shí)現(xiàn)了哈希關(guān)聯(lián),而不是使用MySQL的嵌套環(huán)關(guān)聯(lián),某些場(chǎng)景哈希關(guān)聯(lián)的效率更高很多。
7. 單表查詢有利于后期數(shù)據(jù)量大了分庫分表,如果聯(lián)合查詢的話,一旦分庫,原來的sql都需要改動(dòng)。
8. 上次看到某個(gè)CTO技術(shù)分享,公司規(guī)定底層禁止用join聯(lián)合查詢。數(shù)據(jù)大的時(shí)候確實(shí)慢。
9. 聯(lián)合查詢或許確實(shí)快,但是mysql的資源通常比程序代碼的資源緊張的多。
二、其他的一些回答
情景假設(shè):假設(shè)網(wǎng)站有一個(gè)公司庫版塊,我想搜索某城市的所有公司。
數(shù)據(jù)表:tbl_company (t1)、 tbl_city (t2)。
例1:
t1表中存cityid 根據(jù)id做表連接查詢
select * from t1 inner join t2 on t1.cityid=t2.cityid;
例2:
t1表中存cityName 用戶前臺(tái)點(diǎn)擊上海市,則把上海市的id傳到后臺(tái)(不考慮傳cityName),
根據(jù)id查出cityName select cityName from t2 where cityid= #{cityid};
然后 select * from t1 where cityName = #{cityName};
兩者區(qū)別:例1中只做了一次表關(guān)聯(lián)查詢,例2中分別做了兩次單表查詢。
考慮到數(shù)據(jù)量大,多表連接查詢會(huì)影響查詢效率所以都優(yōu)化為單表查詢。 TP:以上是在不使用索引的情況下
請(qǐng)問哪種效率會(huì)更高些?
答:sql優(yōu)化與業(yè)務(wù)也有關(guān)系,這條語句的查詢會(huì)不會(huì)頻繁,要不要考慮2次連接帶來的開銷,如果這些都不用考慮的話,都沒有索引的情況下,感覺相差不大,2應(yīng)該略優(yōu)于1。
數(shù)據(jù)沒有特別大的情況還是級(jí)聯(lián)查詢快。
對(duì)于傳統(tǒng)的數(shù)據(jù)庫涉及來說, 盡可能減少數(shù)據(jù)庫查詢次數(shù).
BUT, 1. mysql都對(duì)處理連接/斷開連接, 回復(fù)小而簡(jiǎn)單的 查詢是非??斓? 2.現(xiàn)在的網(wǎng)絡(luò)已經(jīng)非??炝? 所以多個(gè)小的查詢對(duì)mysql來說可能更快一些.
最后, 大神也沒有結(jié)論哪個(gè)更好. 呵呵, 其實(shí)整本書都明確表達(dá)一個(gè)意思, 測(cè)試測(cè)試! 做benchmark! 對(duì)于自己的數(shù)據(jù)環(huán)境, 把兩種方式都測(cè)試一下. 用數(shù)據(jù)說話.
三、總結(jié)
個(gè)人建議還是用單表查詢!在應(yīng)用層做數(shù)據(jù)之間的關(guān)聯(lián)會(huì)更好!
以上就是MySql單表查詢與多表連接查詢效率問題的詳細(xì)內(nèi)容,更多關(guān)于MySql單表與多表連接查詢效率的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MySQL性能優(yōu)化之max_connections配置參數(shù)淺析
這篇文章主要介紹了MySQL性能優(yōu)化之max_connections配置參數(shù)淺析,本文著重講解了3種配置max_connections參數(shù)的方法,需要的朋友可以參考下2014-07-07MySql存儲(chǔ)過程和游標(biāo)的使用實(shí)例
我們?cè)趯?shí)際的開發(fā)中會(huì)遇到一些統(tǒng)計(jì)的業(yè)務(wù)功能,如果我實(shí)時(shí)的去查詢的話有時(shí)候會(huì)很慢,此時(shí)我們可以寫一個(gè)存儲(chǔ)過程來實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于MySql存儲(chǔ)過程和游標(biāo)使用的相關(guān)資料,需要的朋友可以參考下2022-04-04Navicat配置mysql數(shù)據(jù)庫用戶權(quán)限問題
這篇文章主要介紹了Navicat配置mysql數(shù)據(jù)庫用戶權(quán)限問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03navicat中創(chuàng)建存儲(chǔ)過程、觸發(fā)器和使用游標(biāo)的簡(jiǎn)單實(shí)例(圖文)
這篇文章主要介紹了navicat中創(chuàng)建存儲(chǔ)過程、觸發(fā)器和使用游標(biāo)的簡(jiǎn)單實(shí)例,需要的朋友可以參考下2017-02-02MySQL8.0?Command?Line?Client輸入密碼后出現(xiàn)閃退現(xiàn)象的原因以及解決方法總結(jié)
我們?cè)诎惭bMYSQL數(shù)據(jù)庫時(shí),經(jīng)常會(huì)出現(xiàn)一些問題,下面這篇文章主要給大家介紹了關(guān)于MySQL8.0?Command?Line?Client輸入密碼后出現(xiàn)閃退現(xiàn)象的原因以及解決方法的相關(guān)資料,需要的朋友可以參考下2023-03-03mysql(master/slave)主從復(fù)制原理及配置圖文詳解
這篇文章主要介紹了mysql(master/slave)主從復(fù)制原理及配置圖文詳解,以前腳本之家小編發(fā)過相關(guān)的內(nèi)容,但這么好的非常少見特分享一下,需要的朋友可以參考下2016-05-05