作者:郭奧門
愛可生 DBLE 研發成員,負責分布式資料庫中間件的新功能開發,回答社群/客戶/内部提出的一般性問題。
本文來源:原創投稿
*愛可生開源社群出品,原創内容未經授權不得随意使用,轉載請聯系小編并注明來源。
本文關鍵字:JOIN、原了解析、分庫分表
問題
前幾天,社群交流群一個小夥伴提出這樣一個問題:

小夥伴說:全局表和分片表的左連接配接能否支援 -- 目前測試 Mycat 結果不對。
很顯然是想要脫坑的 Mycat 使用者,急需找個替代品,主要的是他也找到了,哈哈哈。
場景重制
首先我們建立一個全局表和一個拆分表,各自設定兩個分片節點,全局表在兩個節點資料一緻,拆分表 id=1、2 的在一個節點,id=5000001 的在另一個節點,其中 id=1 和 id=2 的隻有 id 字段值不同、code&content 字段值都一樣。
通過 a.id、b.code 将兩張表左連接配接查詢,結果如小夥伴所言:
Mycat 結果不對。同樣,通過 a.id、b.code 将兩張表左連接配接查詢,結果如下所示;顯而易見實際得到的結果
符合預期!結果探究
根據以上使用 Mycat 和 DBLE 進行 Global 表 Left Join 拆分表查詢得到不同的結果,我們嘗試着使用 EXPLAIN 檢視同一種類型的查詢在執行計劃上會有什麼不同?
Mycat 執行計劃根據上圖執行計劃,我們簡單分析一下。
Mycat 會将 SQL 原封不動的交由分片配置的所有執行個體去執行,然後根據執行結果進行合并,這裡合并隻是簡單的對結果進行累加,很顯然這樣的計劃顯示 Mycat 内部處理邏輯是錯誤的。因為全局表在每個配置的節點都會存儲相同的資料,如果将每個節點和拆分表 Left Join 的結果進行簡單的 UNION ALL 合并,會造成資料的重複,不能保證資料的準确性。有些小夥伴可能猜想 UNION 不是會保證資料不重複嗎?如果用 UNION 是否可行?同樣分析一下。
上述結果仍然得不到我們想要的結果,因為 UNION 隻是解決資料重複的問題,不适用于因為分片而導緻的資料重複問題;試想一下,如果 DBLE 未來通過某種算法可以對各個節點的結果集做一個準确的合并,那麼這樣的問題也就迎刃而解,也會性能方面有個整體的提升。
實際上我們想象中的
X 算法還沒有一個良好的實作和證明,但現在又要解決查詢正确性的問題,那麼 DBLE 是怎麼做的呢?下面我們來看下 DBLE 的執行計劃:
從上面執行計劃來看,簡單分析下流程:
DBLE 内部對于這種查詢作出了一些區分:全局表隻會下發一個執行個體,拆分表都會下發,然後針對結果做合并,這種處理邏輯肯定是沒有錯誤的,隻不過執行計劃看起來相對複雜一些,這也代表在 DBLE 内部實作層面上下了不少功夫,但是這也是為了保證資料準确性而作出的一些犧牲吧。