Multiple Statement

    当前版本的proxy对于multiple statement的支持并不完美,所以希望通过使用multiple statement来减少RPC次数进而达到性能优化的同学请仔细阅读本文档。

    proxy的路由策略如下:

    • proxy parser

    proxy parser在根据SQL选择server时,有以下几点特殊的逻辑:

    1. proxy parser只解析Begin/START TRANSACTON/SET/和其他DML,如果遇到其他单词开头的语句,proxy的parser会直接跳过,认为该语句不包含表名;
    2. proxy parser会按照第一条包含实体表名的statement进行路由,如果整个statement都不包含表名,则将请求发送至上一条SQL所发送的server。
    • server反馈机制

    OBServer会根据执行计划的类型,来告诉proxy是否将请求路由至正确的server,如果路由失败,proxy会更新location,当前的反馈机制为:server返回第一条DML的命中情况。

    示例

    以下都是从proxy路由的角度看待问题的,server端逻辑可能还有其他限制。

    • 比较推荐使用的语句

    • 以下几种情况(select可以等价替换成update/delete/replace/insert,下同),proxy能够将请求发送至正确的server,并且server能够按照proxy的命中情况进行反馈:

    1. begin; select * from t1; commit;
    2. set @@autocommit = 1; insert into t1 values(); set @@autocommit = 0;
    3. select * from t1; insert into t2 values;
    4. set @@ob_trx_timeout = 10000000; begin; select * from t1; commit;
    • 以下几种情况,proxy会将请求发送至上一个SQL所使用的server
    1. create table t1 (id int primary key); create table t2 (id int primary key);
    • 不建议使用的语句

    • 以下几种情况(第一个DML是非实体表),proxy能够将请求发送至正确的server,但是server反馈的信息可能不准,不建议使用:

    1. select '1'; select * from t1;
    2. select '1' from dual; select * from t1;
    • 以下几种情况,proxy可能能够将请求路由至正确的server,但是server端反馈信息可能不准,不建议使用:
    1. create table t1 (id int primary key); insert into t1 values();
    • 以下几种情况,proxy会强制将请求路由至上一次使用的server,server断反馈信息可能不准,不建议使用:
    1. show warnings; select * from t1;
    2. show count(\*) errors; select * from t1;

    使用建议

    1. 1. 将一个事务的所有语句(最好只有begin/set/commitDML)放在一个multiple stmtement里面;
    2. 2. DDLDML不要在同一个multiple stmtement里面;

    分区表支持

    • 分区表支持功能列表

    • 支持partition by key,hash,range,range column,支持一级二级分区的任意组合

    • 支持所有的字段类型(varchar,int,datetime等)
    • 支持所有的dml语句(select、insert、delete、update、replace)
    • 支持简单的比较运算符>,>=,=,<=,<,IN

    下面是一些简单示例,如果你的sql类型和下面的sql类似,可以认为就是支持分区路由:

    1. select * from t1 where c1 = 1;
    2. select * from t1 where c1 = '1';
    3. select * from t1 where c1 = '2016-03-01 00:00:00';
    4. select * from t1 where c1 > 1 and c1 < 10;
    5. select * from t1 where c1 = 1 and c2 > 0 and c2 < 10;
    6. update t1 set c2 = 1 where c1 in (0, 1, 2);
    7. insert into t1(c1, c2) values ('1', '2');
    8. insert into t1 values ('1', '2');
    • 分区表不支持的功能

    • 不支持带有多列的range column和key

    1. create table t1 (c1 int, c2 int, primary key(c1, c2)) partition by key(c1, c2);
    • 不支持向量比较
    1. select * from t1 where (c1, c2) > (0, 1);
    • 不支持函数计算
    1. select * from t1 where substr(c1, 2, 1) = '0';
    • 不支持表达式计算
    1. select * from t1 where c1 = 1 + 2