分页性能
性能瓶颈
查询偏移量过大的分页会导致数据库获取数据性能低下,以MySQL为例:
SELECT * FROM t_order ORDER BY id LIMIT 1000000, 10
这句SQL会使得MySQL在无法利用索引的情况下跳过1000000条记录后,再获取10条记录,其性能可想而知。
在分库分表的情况下(假设分为2个库),为了保证数据的正确性,SQL会改写为:
SELECT * FROM t_order ORDER BY id LIMIT 0, 1000010
即将偏移量前的记录全部取出,并仅获取排序后的最后10条记录。这会在数据库本身就执行很慢的情况下,进一步加剧性能瓶颈。 因为原SQL仅需要传输10条记录至客户端,而改写之后的SQL则会传输1,000,010 * 2的记录至客户端。
ShardingSphere的优化
ShardingSphere进行了2个方面的优化。
1)首先,采用流式处理 + 归并排序的方式来避免内存的过量占用。由于SQL改写不可避免的占用了额外的带宽,但并不会导致内存暴涨。 与直觉不同,大多数人认为ShardingSphere会将1,000,010 * 2记录全部加载至内存,进而占用大量内存而导致内存溢出。 由于每个结果集的记录是有序的,因此ShardingSphere每次比较仅获取各个分片的当前结果集记录 10条 ,驻留在内存中的记录仅为当前路由到的分片的结果集的当前游标指向,即 只有 20条。
对于本身即有序的待排序对象,归并排序的时间复杂度仅为O(n),性能损耗很小。
2)其次,ShardingSphere对仅落至单分片的查询进行进一步优化。