分页

    查询偏移量过大的分页会导致数据库获取数据性能低下,以MySQL为例:

    这句SQL会使得MySQL在无法利用索引的情况下跳过1000000条记录后,再获取10条记录,其性能可想而知。 而在分库分表的情况下(假设分为2个库),为了保证数据的正确性,SQL会改写为:

    即将偏移量前的记录全部取出,并仅获取排序后的最后10条记录。这会在数据库本身就执行很慢的情况下,进一步加剧性能瓶颈。 因为原SQL仅需要传输10条记录至客户端,而改写之后的SQL则会传输1,000,010 * 2的记录至客户端。

    ShardingSphere的优化

    ShardingSphere进行了2个方面的优化。

    其次,ShardingSphere对仅落至单分片的查询进行进一步优化。 落至单分片查询的请求并不需要改写SQL也可以保证记录的正确性,因此在此种情况下,ShardingSphere并未进行SQL改写,从而达到节省带宽的目的。

    由于LIMIT并不能通过索引查询数据,因此如果可以保证ID的连续性,通过ID进行分页是比较好的解决方案:

    或通过记录上次查询结果的最后一条记录的ID进行下一页的查询:

    Oracle和SQLServer的分页都需要通过子查询来处理,ShardingSphere支持分页相关的子查询。

    目前不支持rownum + BETWEEN的分页方式。

    • SQLServer

    支持使用TOP + ROW_NUMBER() OVER配合进行分页:

    1. SELECT * FROM (SELECT TOP (?) ROW_NUMBER() OVER (ORDER BY o.order_id DESC) AS rownum, * FROM t_order o) AS temp WHERE temp.rownum > ? ORDER BY temp.order_id

    支持SQLServer 2012之后的OFFSET FETCH的分页方式:

    目前不支持使用WITH xxx AS (SELECT …)的方式进行分页。由于Hibernate自动生成的SQLServer分页语句使用了WITH语句,因此目前并不支持基于Hibernate的SQLServer分页。 目前也不支持使用两个TOP + 子查询的方式实现分页。

    • MySQL, PostgreSQL