連表查詢和子查詢在實際中的使用問題和分析

前言:

1.對於mysql,不推薦使用子查詢和join是因爲本身join的效率就是硬傷,一旦數據量很大效率就很難保證,強烈推薦分別根據索引單表取數據,然後在程序裏面做join,merge數據。

2.子查詢就更別用了,效率太差,執行子查詢時,MYSQL需要創建臨時表,查詢完畢後再刪除這些臨時表,所以,子查詢的速度會受到一定的影響,這裏多了一個創建和銷燬臨時表的過程。

3.如果是JOIN的話,它是走嵌套查詢的。小表驅動大表,且通過索引字段進行關聯。如果表記錄比較少的話,還是OK的。大的話業務邏輯中可以控制處理。

4.數據庫是最底層的,瓶頸往往是數據庫。建議數據庫只是作爲數據store的工具,而不要添加業務上去。

一、放棄連表查詢,在應用層關聯的優勢:

1.讓緩存的效率更高許多應用程序可以方便地緩存單表查詢對應的結果對象。如果關聯中的某個表發生了變化,那麼就無法使用查詢緩存了,而拆分後,如果某個表很少改變,那麼基於該表的查詢就可以重複利用查詢緩存結果了。
將查詢分解後,執行單個查詢可以減少鎖的競爭。
2.在應用層做關聯,可以更容易對數據庫進行拆分,更容易做到高性能和可擴展。
3..查詢本身效率也可能會有所提升。查詢id集的時候,使用IN()代替關聯查詢,可以讓MySQL按照ID順序進行查詢,這可能比隨機的關聯要更高效。
4.可以減少冗餘記錄的查詢。在應用層做關聯查詢,意味着對於某條記錄應用只需要查詢一次,而在數據庫中做關聯查詢,則可能需要重複地訪問一部分數據。從這點看,這樣的重構還可能會減少網絡和內存的消豔。
更進一步,這樣做相當於在應用中實現了哈希關聯,而不是使用MySQL的嵌套循環關聯。某些場景哈希關聯的效率要高很多。


二、放棄連表查詢,在應用層關聯的使用場景:

1.當應用能夠方便地緩存單個查詢的結果的時候
2.當可以將數據分佈到不同的MySQL服務器上的時候
3.當能夠使用IN()的方式代替關聯查詢的時候
4.併發場景多,DB查詢頻繁,需要分庫分表


三、不推薦使用join進行連表查詢的原因: 

1.DB承擔的業務壓力大,能減少負擔就減少。當表處於百萬級別後,join導致性能下降; 

2.分佈式的分庫分表。這種時候是不建議跨庫join的。目前mysql的分佈式中間件,跨庫join表現不良。 

3.修改表的schema,單表查詢的修改比較容易,join寫的sql語句要修改,不容易發現,成本比較大,當系統比較大時,不好維護。

四、不使用join的解決方法: 

業務層,單表查詢出數據後,作爲條件給下一個單表查詢。也就是子查詢。 會擔心子查詢出來的結果集太多。mysql對in的數量沒有限制,但是mysql限制整條sql語句的大小。通過調整參數max_allowed_packet ,可以修改一條sql的最大值。建議在業務上做好處理,限制一次查詢出來的結果集是能接受的。

五、再來說說join查詢的好處:

1.做分頁查詢:

關聯查詢的好處時候可以做分頁,可以用副表的字段做查詢條件,在查詢的時候,將副表匹配到的字段作爲結果集,用主表去in它,但是問題來了,如果匹配到的數據量太大就不行了,也會導致返回的分頁記錄跟實際的不一樣,解決的方法可以交給前端,一次性查詢,讓前端分批顯示就可以了,這種解決方案的前提是數據量不太,因爲sql本身長度有限。

總結:

1.數據庫是作爲數據存儲的地方,能用程序解決的問題,不應由數據庫去完成,比如對數據的加工(使用一些函數)會導致索引失效,對數據的加工處理在業務層完成

2.在數據量極大的項目裏,連表查詢會消耗大量數據庫資源,想比之下,程序運算消耗的是服務器資源,而現在應用的瓶頸還在數據庫上,服務器可以通過增量分壓來擴容,數據庫雖然也可以,但是多個之間的數據同步是個很難處理的問題,由此促進了緩存技術的發展,否則也不會出現緩存爲王這種認知了

3.在數據量不大的項目裏,使用連表查詢要比子查詢嵌套效率要高一些,連表查詢的關鍵點是索引的運用,索引的合理性可以大大增強連表的效率,但是相對的數據過多也是對重組索引的一種負擔,應儘量選擇整型變量來加快索引的重組

4.連表查詢給前臺發送數據時用分頁或者懶加載的方式也能減小數據庫負擔,

5.雖然php程序相比其他程序運算慢點,但也不是很離譜,相比兩個大表聯合查詢的等待時間,分兩次查詢再由php組合的速度可能會更快.

6.就實際工作中,很多大公司都嚴禁使用連表查詢,我相信這麼做是有依據,而且連表查詢可以通過優化轉化子查詢的方式去避免.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章