MyCat Join 专题 ---- share join

share join:分片表 join

目录

零:分片表实操


 

零:分片表实操

ShareJoin 是一个简单的跨分片 Join,目前支持 2 个表的 join,原理就是解析 SQL 语句,拆分成单表的 SQL 语句执行,然后把各个节点的数据汇集。有限制,不同分盘规则最多两表操作

受限制的原因主要在于:各表的分片后的数据可能不在同一个分片中。所以会导致问题。

特殊情况:多个表使用同一种分片规则,且分片规则属性相同。在 share join 可以支持多与两表的查询。以下是测试样例:

schemel.xml,注意点就是我添加了两个范围分片的表 wyptable lxjtable


    
        
            
                
            
            
        
                 
        
        
              
表名 所属节点 切分列 切分规则
lsqtable dn$1-2 id mod-long 取模
lsqtable_supplement dn$1-2 id 继承 ER 父类切分规则 mod-long
lsqtable_supplement_items dn$1-2 parent_id 继承 ER 父类切分规则 mod-long
lsqtable_supplement_other dn$1-2 id 继承 ER 父类切分规则 mod-long
wyptable dn$1-2 id

auto-sharding-long 范围分片,但是范围

给的很大,数据都被路由到 dn1 中

lxjtable dn$1-2 id

auto-sharding-long 范围分片,但是范围

给的很大,数据都被路由到 dn1 中

jointable dn$1-2 id global 全局表,路由到所有节点插入
otherjointable dn$1-2 id global 全局表,路由到所有节点插入

 

查询条件如下:

表 lxjtable 和 wyptable 进行关联查询,可以查询且可以查询到执行计划,因为新添加的两个表使用的同种切分规则,且规则一致。(多个表没试,想使用的小伙伴可以试下)

EXPLAIN SELECT *
FROM lxjtable lxj
INNER JOIN wyptable wyp ON lxj.id = wyp.id

dn1    SELECT *   FROM lxjtable lxj   INNER JOIN wyptable wyp ON lxj.id = wyp.id
dn2    SELECT *   FROM lxjtable lxj   INNER JOIN wyptable wyp ON lxj.id = wyp.id

如果两个不同切分规则的表进行 join 就会触发 share join 操作,不能查出查询计划。如 lsqtable 和 lxjtable 两表,无执行计划,只有结果集。但是仍可以联查全局表。

EXPLAIN SELECT *
FROM lxjtable lxj
INNER JOIN lsqtable lsq ON lxj.id = lsq.id

从日志中可以看出 cat.log

INFO [$_NIOREACTOR-5-RW] (io.mycat.catlets.JoinParser.parserTable(JoinParser.java:101)) - table lsqtable Alias:lsq Hints:[]
INFO [$_NIOREACTOR-5-RW] (io.mycat.catlets.JoinParser.parser(JoinParser.java:79)) - SQL: SELECT * FROM lxjtable lxj INNER JOIN lsqtable lsq ON lxj.id = lsq.id
INFO [$_NIOREACTOR-5-RW] (io.mycat.catlets.ShareJoin.processSQL(ShareJoin.java:172)) - Catlet exec:dn1,dn2, sql:select *, id from lxjtable
INFO [$_NIOREACTOR-0-RW] (io.mycat.cache.DefaultLayedCachePool.createChildCache(DefaultLayedCachePool.java:80)) - create child Cache: mydb_LSQTABLE for layered cache TableID2DataNodeCache, size 10000, expire seconds 18000
INFO [$_NIOREACTOR-0-RW] (io.mycat.catlets.ShareJoin.createQryJob(ShareJoin.java:275)) - SQLParallJob:dn1,dn2, sql:select * from lsqtable where id in (1,2)
INFO [$_NIOREACTOR-5-RW] (io.mycat.sqlengine.EngineCtx.onJobFinished(EngineCtx.java:194)) - all job finished  for front connection: ServerConnection [id=1, schema=mydb, host=0:0:0:0:0:0:0:1, user=root,txIsolation=3, autocommit=true, schema=mydb]
INFO [$_NIOREACTOR-5-RW] (io.mycat.sqlengine.EngineCtx.writeEof(EngineCtx.java:180)) - write  eof ,packgId:13
INFO [$_NIOREACTOR-5-RW] (io.mycat.catlets.ShareJoin$1.onAllJobFinished(ShareJoin.java:189)) - 发送数据OK
INFO [$_NIOREACTOR-5-RW] (io.mycat.catlets.JoinParser.parserTable(JoinParser.java:101)) - table lsqtable Alias:lsq Hints:[]
INFO [$_NIOREACTOR-5-RW] (io.mycat.catlets.JoinParser.parser(JoinParser.java:79)) - SQL: SELECT * FROM lxjtable lxj INNER JOIN lsqtable lsq ON lxj.id = lsq.id
INFO [$_NIOREACTOR-5-RW] (io.mycat.catlets.ShareJoin.processSQL(ShareJoin.java:172)) - Catlet exec:dn1,dn2, sql:select *, id from lxjtable
INFO [$_NIOREACTOR-4-RW] (io.mycat.catlets.ShareJoin.createQryJob(ShareJoin.java:275)) - SQLParallJob:dn1,dn2, sql:select * from lsqtable where id in (1,2)
INFO [$_NIOREACTOR-0-RW] (io.mycat.sqlengine.EngineCtx.onJobFinished(EngineCtx.java:194)) - all job finished  for front connection: ServerConnection [id=1, schema=mydb, host=0:0:0:0:0:0:0:1, user=root,txIsolation=3, autocommit=true, schema=mydb]
INFO [$_NIOREACTOR-0-RW] (io.mycat.sqlengine.EngineCtx.writeEof(EngineCtx.java:180)) - write  eof ,packgId:13
INFO [$_NIOREACTOR-0-RW] (io.mycat.catlets.ShareJoin$1.onAllJobFinished(ShareJoin.java:189)) - 发送数据OK

比较重要的点:基本上就是将 A share join B 的操作,分为两部分左侧查询和右侧查询,左表  select *, id  右侧  select * in  操作。之后根据左侧的 id 替换右侧的结果集,合并数据。

Catlet exec:dn1,dn2, sql:select *, id from lxjtable
SQLParallJob:dn1,dn2, sql:select * from lsqtable where id in (1,2)

且三表联查时将发生错误。如下。

EXPLAIN SELECT *
FROM lxjtable lxj
INNER JOIN lsqtable lsq ON lxj.id = lsq.id
INNER JOIN wyptable wyp ON lxj.id = wyp.id

> 2013 - Lost connection to MySQL server during query
> 时间: 0.02s

但是关联多个全局表是可以的。

其实就是,不过多少个表,只要是以相同的分片规则分在一个节点(全局表每个节点冗余),每个分片都可以自主的进行数据关联,之后进行合并。但是以不同分片规则的表就不一样了。因为相关联的节点可能处在不同的节点中。这样只能先按分片键查出第一个表的相关数据。之后使用 in 关键字来查第二个表。所以最好在第一个表查询时加入 on 关键字来降低第一个结果集的数量。

你可能感兴趣的:(MyCat从入门到放弃)