搭建了一个简单的Spider引擎的测试环境,数据900万条左右,id是500万以下的放在分区1,500万以上的放在分区2。表的创建语句如下:
drop database if exists myspider;
create database myspider;
use myspider;
Create table tbl_t(
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
name string
) engine = Spider
Connection ' table "tbl_t", user "msandbox", password "msandbox" '
partition by range ( id ) (
partition pt1 values less than (5000000) comment 'host "rdb1", port "3306"',
partition pt2 values less than (MAXVALUE) comment 'host "rdb2", port "3306"'
);
发现,执行带limit的查询语句时速度极慢。下边的简单查询居然用了13分钟。
select * from tbl_t1 order by id desc limit 1;
id列是有索引的,分别在两个分区服务器(rdb1,rdb2)里执行同样的语句,速度都在1毫秒左右。这是什么原因呢?
再次在Spider服务器执行同样的查询,然后在rdb1、rdb2里执行show processlist,发现时间都花在了sending data上,先rdb1再rdb2,每个都sending了6分多。
终于明白了,Spider引擎在利用了condition pushdown后,虽然可以把查询条件传递到分区服务器,但是却不能传递limit。
为什么不让limit可以传递呢?limit n 这样的简单limit,实现起来不难呀,只要在各个分区服务器分别limit n 一下,再把各个分区服务器的结果集合并在一起,再做一次limit n 就可以了。但是,对于limit offset,n 这样的查询,就不能再各个分区服务器简单的执行limit offset,n 了,至少要传递 limit offset+n 才可以,然后在Spider服务器把各个分区的服务器的结果集合并在一起,做一次 limit offset,n 。不过至少现在的Spider引擎还没有实现这个功能。
如果在查询中加入where条件,限制分区结果集的数量(减少sending data 的时间),即使没有传递limit,也会快很多,这是使用Spider引擎需要注意的。