面試官:MySQL 使用多表 JOIN 有哪些危害?
多表 JOIN 是好多公司嚴(yán)格禁止的 SQL 寫法,那它到底有哪些危害呢?今天來聊一下這個話題。
圖片
1.資源壓力
多表 JOIN,尤其是 JOIN 涉及的表存在大表的情況下,數(shù)據(jù)庫會承受巨大的計算和內(nèi)存壓力。
在高并發(fā)場景下,多表 JOIN 可能占用大量的 join buffer,造成內(nèi)存壓力增加,SQL 執(zhí)行時間增大,進(jìn)一步造成大量連接不能釋放,連接被耗盡。最終結(jié)果就是整個數(shù)據(jù)庫實(shí)例響應(yīng)慢,客戶端因?yàn)楂@取不到連接而失敗。
2.性能風(fēng)險
JOIN 語句的性能依賴于正確的索引,如果 ON 或 WHERE 子句中的列沒有加索引,執(zhí)行 JOIN 語句需要進(jìn)行全表掃描。JOIN 的表越多,全表掃描的成本越高,最壞情況下可能達(dá)到呈笛卡爾積的數(shù)量級。尤其是 JOIN 語句中有大表(比如數(shù)據(jù)量百萬級別)時,一個復(fù)雜的多表 JOIN 語句響應(yīng)時間可能會達(dá)到分鐘級別,這會造成大量上游系統(tǒng)請求超時,業(yè)務(wù)不能正常進(jìn)行。
3.鎖等待
InnoDB 默認(rèn)隔離級別是可重復(fù)讀,在可重復(fù)讀隔離級別下,JOIN 查詢可能會對涉及的行加間隙鎖,如果 JOIN 的表比較多,可以會有多張表的多條記錄和間隙被鎖定,造成其他事務(wù)的鎖等待,甚至可能造成死鎖,這會嚴(yán)重降低系統(tǒng)吞吐量。
4.可維護(hù)性差
多表 JOIN 的 SQL 涉及多張表、多個 JOIN 條件,往往 where 子句也會有多個篩選條件,可讀性差。而復(fù)雜 JOIN 往往包含了復(fù)雜業(yè)務(wù)邏輯,面對需求修改,如果不是 SQL 原作者,很難理解和維護(hù)。對測試而言,測試用例也很難覆蓋所有場景,導(dǎo)致生成問題。
5.影響分庫分表
隨著業(yè)務(wù)量上升,數(shù)據(jù)量也會變大,單表存儲會影響到 SQL 性能,這個時候就需要考慮分庫分表。如果一個多張表 JOIN 的 SQL 語句中涉及多張表要分庫和分表,那就必須讓這些表的同一筆業(yè)務(wù)數(shù)據(jù)拆分到同一個數(shù)據(jù)庫節(jié)點(diǎn)上,同時 JOIN 的表名也需要修改,這涉及的改造和測試 工作難度非常大。
6.影響信創(chuàng)改造
如果涉及信創(chuàng)改造,多表 JOIN 的 SQL 除了數(shù)據(jù)遷移外,還需要評估這個 SQL 在新庫上的執(zhí)行效率,給信創(chuàng)改造增加了很多額外的工作。






























