性能建議:
盡量避免使用 Left join 或 Right join,而用 Inner join 在使用 Left join 或 Right join 時, ON 會優先執行, where 條件在最后執行,所以在使用過程中,條件盡可能的在 ON 語句中判斷,減少 where 的執行。
少用子查詢,而用 join。
Mycat 目前版本支持跨分片的 join,主要實現的方式有四種:全局表, ER 分片, catletT(人工智能)和 ShareJoin, ShareJoin 在開發版中支持,前面三種方式 1.3.0.1 支持 。
1. 全局表
一個真實的業務系統中,往往存在大量的類似字典表的表格,它們與業務表之間可能有關系,這種關系,可以理解為“標簽” ,而不應理解為通常的“主從關系” ,這些表基本上很少變動。
考慮到字典表具有以下幾個特性:
• 變動不頻繁
• 數據量總體變化不大
• 數據規模不大,很少有超過數十萬條記錄。
鑒於此, MyCAT 定義了一種特殊的表,稱之為“全局表” ,全局表具有以下特性:
• 全局表的插入、更新操作會實時在所有節點上執行,保持各個分片的數據一致性
• 全局表的查詢操作,只從一個節點獲取
• 全局表可以跟任何一個表進行 JOIN 操作
全局表的配置如下:
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
2. ER Join
MyCAT 借鑒了 NewSQL 領域的新秀 Foundation DB 的設計思路, Foundation DB 創新性的提出了 Table Group 的概念,其將子表的存儲位置依賴於主表,並且物理上緊鄰存放,因此徹底解決了 JION 的效率和性能問題,根據這一思路,提出了基於 E-R 關系的數據分片策略,子表的記錄與所關聯的父表記錄存放在同一個數據分片上。
customer 采用 sharding-by-intfile 這個分片策略,分片在 dn1,dn2 上, orders 依賴父表進行分片,兩個表的關聯關系為 orders.customer_id=customer.id。於是數據分片和存儲的示意圖如下
配置示例:
<table name="customer" dataNode="dn1,dn2" rule="sharding-by-intfile"> <childTable name="orders" joinKey="customer_id" parentKey="id"/> </table>
3. Share join
ShareJoin 是一個簡單的跨分片 Join,基於 HBT 的方式實現。
目前支持 2 個表的 join,原理就是解析 SQL 語句,拆分成單表的 SQL 語句執行,然后把各個節點的數據匯集
支持任意配置的兩個表,如:
<table name="A" dataNode="dn1 " rule="auto-sharding-long" />
<table name="B" dataNode=" dn2,dn3" rule="auto-sharding-long" />
上面的配置是官方文檔中的示例,但是我試的時候,連 mycat 都啟動不起來。把這兩個配置中的 rule 去掉,加上 primaryKey="id" autoIncrement="true" , mycat 可以啟動,但是運行這兩個表的 join 查詢,會拋錯。
4. catlet(人工智能)
mycat 提供了一些接口,需要自己定邏輯怎么把不同分片的表 join 起來。