分表性能优化

Posted by Shi Hai's Blog on September 12, 2023

基本概念介绍

流式查询:返回一个迭代器从而降低内存占用。

面临的问题

单个数据库有20+个分表,每个分表有2w+条记录,直接用Mybatis和Shardingsphere查询所有表中数据,服务就会长期在查询数据库,结果耗时大概需要30分钟+。
导致这个现象的原因我估计是数据层通过流式计算和归并排序算法操作防止占用大量内存却导致时间开销增加了。

技术手段

shardingSphere

ShardingSphere在查询单个库的同个SQL语句查询时会通过UNION ALL进行归并操作来降低对数据库连接资源的消耗。 在这个降低数据库连接资源损耗的同时也导致数据库查询从并发变为了串行,增加了时间开销。 结论:我在用20个分表,50w+条记录1GB+数据上测试,不用shardingSphere的串行多次查询效率比用shardingSphere中间件节省70%+查询时间。

myCat

TBD

结论

mysql limit语句性能分析

在mysql中,limit x, y或者limit y offset x实际上是等价操作,都是要获取表前面x条记录,所以效率不是很高。用where id > x limit y的执行效率会更高,因为这个执行查询类似于一个指针查询,不需要获取前面x条记录。

like vs regexp

like的匹配效率优于regexp。分析 在数据库中不用like而直接用查询操作会更快,但是这样会占用更多的网络IO。 另外所有数据拉到应用程序中,要判断一下内存占用量是否过大,需要使用类似流式查询进行处理。详情

查询优化

数据库查询会占用一定的网络IO,程序内存占用的容许的情况下可以调大fetchsize来提升查询效率。
另外,如果想把数据库全表查询后在程序中做一定计算判断,如果数据量特别大的情况可能会导致OOM情况,此时就需要通过流式查询降来降低内存开销(如:mybatis可以利用resultHandler进行判断处理)。

数据库表

表尽量用精确长度的字段,用longtext这种会比较耗时,另外按需返回查询字段也能节省一定时间。

参考文章