如何在不带分表字段的情况下通过mycat进行大批量的数据查询

  之前项目中采用了mycat对mysql数据库进行分表,大大提高了在携带分表字段下的数据操作的效率,但是也带来了一个比较恶心的问题,因为在业务中需要对某些表中的数据按照一定的维度进行数据统计,然而数据被分散在了共计240个分片上,从最开始处理这块代码到最后成功搞定,走了不少弯路,下面来说说:

1. 像操作mysql一样直接从mycat查询

这样好处是代码简单,但是坏处显而易见,在不带分片字段的情况下,mycat不知道数据具体都在哪个分片上,故而会将查询sql以并发的形式发给所有的分片数据库,造成了数据库的性能下降明显,严重影响了核心业务对数据库的需求,而且在某些情况下还会导致内存溢出。

所以这种方式在实际测试后被排除掉。


2. 按照主键的范围通过mycat取数据

本质和1的方法类似,凡是改进点在于,因为表有主键id,是自增长的,所以考虑将数据按照id进行切分,循环查询,最大限度的减小对数据库的压力。具体来讲,就是先查出数据库中id最大值,比如最大值为100,那么就按照id从1-50,51-100这样的范围查找数据,一方面id是索引,查找很快,另一方面,返回的数据量不超过id差值和分片之和的乘积,也就保证了mycat不会内存溢出。然而在后续测试中发现,相对于一方法确实加快了,而且也不会内存溢出,但是最致命的问题在于id的最大值,可能在某些情况下会非常大,比如说有几万亿,那么这个程序可能就无法在规定时间内执行完毕了,所以这种方法也被过滤。


3. 利用mycat自带的语法指定节点多线程遍历

1,2的方法都有明显的缺点,就是在不带分片字段的情况下,会到所有的分片中进行查询,这样导致数据库服务器压力很大,会影响对外业务,那么就想到了脱离mycat直接连mysql,可是这种方式就需要完全脱离框架内的对数据库操作的那一套方法,另起炉灶,任务难度不是一般的大。。。于是想到mycat应该会有一些方法能解决这个问题,去翻看“mycat权威指南”发现了mycat支持一种特别的语法,可以指定数据节点,既然能指定数据节点,那么不就相当于每次只到一个库中查询,不就没有了1,2的问题,代码如下

	<select id="selectData" resultType="java.lang.Integer"
		parameterType="com.test.model.LimitNumModel">
		/**mycat:dataNode=${dataNodeName}*/select
		*
		from
		t_product a
		WHERE 
		a.order_id is null
	</select>

这样来就可以利用多线程来操作mycat对特定数据节点进行数据读取,就直接操作mysql数据库一样了,这样就解决了在方法1,2中面对的2个难题:

1. 不带分片字段,mycat发给所有数据库,造成数据库服务压力过大。

2. 返回的数据量无法控制,排序等复杂操作会导致内存溢出。


  虽然解决了上述2个问题,且通过增加读取线程起到了一定的作用,然而读取的速度还是比较慢,所以认为如果在不带分片字段的情况下去查询mycat的话,能避免就避免。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值