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





























