分页性能

性能瓶颈

查询偏移量过大的分页会导致数据库获取数据性能低下,以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对仅落至单分片的查询进行进一步优化。 落至单分片查询的请求并不需要改写SQL也可以保证记录的正确性,因此在此种情况下,ShardingSphere并未进行SQL改写,从而达到节省带宽的目的。

分页方案优化

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

SELECT * FROM t_order WHERE id > 100000 AND id <= 100010 ORDER BY id

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

SELECT * FROM t_order WHERE id > 100000 LIMIT 10

分页子查询

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

Oracle

支持使用rownum进行分页:

SELECT * FROM (SELECT row_.*, rownum rownum_ FROM (SELECT o.order_id as order_id FROM t_order o JOIN t_order_item i ON o.order_id = i.order_id) row_ WHERE rownum <= ?) WHERE rownum > ?

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

SQLServer

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

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的分页方式:

SELECT * FROM t_order o ORDER BY id OFFSET ? ROW FETCH NEXT ? ROWS ONLY

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

MySQL, PostgreSQL

MySQL和PostgreSQL都支持LIMIT分页,无需子查询:

SELECT * FROM t_order o ORDER BY id LIMIT ? OFFSET ?

sharding子查询_ShardingSphere 分页相关推荐

  1. sharding子查询_分页及子查询

    分页及子查询 Sharding-JDBC完全支持MySQL.PostgreSQL和Oracle的分页查询,SQLServer由于分页查询较为复杂,仅部分支持. 分页性能 性能瓶颈 查询偏移量过大的分页 ...

  2. Mysql进阶学习(六)子查询与分页查询

    Mysql进阶学习(六)子查询与分页查询 进阶7:子查询 1.含义: 2.分类: 3.where或having后面 3.1 特点: 3.2.标量子查询★ 案例1:谁的工资比 Abel 高? 案例2:返 ...

  3. sharding子查询_sharding-JDBC内幕之subquery

    subquery 子查询指一个查询语句嵌套在另一个查询语句内部的查询,在 SELECT 子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或者多个表,子查询中常用的操作符有 ...

  4. SQL 总结(索引index、子查询、分页、开窗函数等)

    索引index(相当于创建目录) 优点:提高查询效率. 缺点:占空间,并且添加.更新.删除数据的时候同步更新索引,会降低insert.update.delete的速度.在where上创建索引. 预读取 ...

  5. day03(连接查询,子查询,分页查询)

    sql99标准 -- sql99 #一.内连接 /* 语法:SELECT 查询列表 FROM 表名1 别名[INNER] JOIN 表名2 别名 ON 连接条件 WHERE 筛选条件 GROUP BY ...

  6. MySQL-数据操作-分组查询-连接查询-子查询-分页查询-联合查询

    文章目录 ==分组查询== 基础 案例 特点 分组查询中的筛选条件分为两类 注意事项 分组查询案例 案例 ==连接查询== 概述 ==sql92标准== 概述 等值连接 非等值连接 自连接 案例 == ...

  7. mysql对结果再查询_mysql 再查询结果的基础上查询(子查询)

    SELECT A.wx_name, A.wx_litpic, B . * FROM ( SELECT uid, COUNT( * ) AS daticishu FROM statements WHER ...

  8. selec查询、分页查询及优化

    1. select查询 select _column,_column from _table [where Clause] [limit N][offset M] 解析:LIMIT 子句可以被用于强制 ...

  9. mysql数据库入门教程(5):多表操作(连接查询,子查询,分页查询,联合查询)

    前文介绍了单表查询:mysql数据库入门教程(4):查询讲解大全 今天介绍下多表查询 一.连接查询 含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询 先送上下面所讲用到的sql脚本 h ...

最新文章

  1. 在批处理中运行.sql文件
  2. 【Android LibGDX游戏引擎开发教程】第07期:中文字体的显示和绘制(上)
  3. RMAN之一:快速入门
  4. 有趣!机器学习预测《守望先锋》里的赢家
  5. Python中的魔法方法
  6. 深度学习(06)-- Network in Network(NIN)
  7. java安装后在哪里打开_冷却塔声屏障安装后降噪效果不理想,原因出在哪里?...
  8. CListCtrl控件的使用指南 (转)
  9. Case:MySQL Federated存储引擎引起的慢SQL优化
  10. redis 验证消息队列也是写磁盘的
  11. LLDB使用详解以及断点调试教程
  12. Intel 8042键盘控制器详细介绍
  13. 威纶通触摸屏上传错误_威伦触摸屏程序上传方式
  14. 网络疯传华为面试题:800公斤牛,过承重700公斤的桥,有答案了?
  15. xp计算机怎么共享网络,xp系统手机usb共享网络上网,xp共享上网-
  16. 鸿蒙系统无限穿越,无限穿越之至尊无上
  17. 阿里直播平台的架构演进
  18. Joel Spolsky给计算机专业学生的七个建议
  19. Type-C潮流下 如何衡量一款数据线好坏?
  20. 【科普】浅谈NB-IoT

热门文章

  1. 人工智能最前线-金融科技永无止境的进化
  2. 日积月累Day2《为什么家庭会生病》
  3. 做好本职工作的5条理由
  4. htc one android版本,四种版本三种双卡 行货版HTC One发布
  5. Markdown 语法实现文字设置对齐方向、颜色、字体大小
  6. iOS图片显示模式(UIImageView)
  7. 智慧灯杆运行维护要求
  8. 2022-2028全球与中国智慧灯杆市场现状及未来发展趋势
  9. mysql里面guid_数据库中GUID的生成
  10. 第1章 Python编程基础