Sharding-JDBC 源码之 SQL 执行

Sharding-JDBC 系列

  1. 第一篇 Sharding-JDBC 源码之启动流程分析
  2. 第二篇 Sharding-JDBC 源码之 SQL 解析
  3. 第三篇 Sharding-JDBC 源码之 SQL 路由
  4. 第四篇 Sharding-JDBC 源码之 SQL 改写
  5. 第五篇 Sharding-JDBC 源码之 SQL 执行(本文)

Sharding-JDBC 使用执行引擎将路由和改写完成之后的真实SQL安全且高效发送到底层数据源执行。 它不是简单地将SQL通过JDBC直接发送至数据源执行;也并非直接将执行请求放入线程池去并发执行。它更关注平衡数据源连接创建以及内存占用所产生的消耗,以及最大限度地合理利用并发等问题。 执行引擎的目标是自动化的平衡资源控制与执行效率。

连接模式

  • 从资源控制的角度看,业务方访问数据库的连接数量应当有所限制。 防止某一个业务将数据库连接的资源耗尽,以致于影响其他业务的正常访问。 特别是一个不带分片键的逻辑SQL将落入到同库的多张真实表上。
  • 从执行效率的角度看,为每个分片查询维持一个独立的数据库连接,可以更加有效的利用多线程来提升执行效率。 为每个数据库连接开启独立的线程,可以将I/O所产生的消耗并行处理。为每个分片维持一个独立的数据库连接,还能够避免过早的将查询结果数据加载至内存。 独立的数据库连接,能够持有查询结果集游标位置的引用,在需要获取相应数据时移动游标即可。
内存限制模式
  • 使用此模式的前提是,Sharding-JDBC 对一次操作所耗费的数据库连接数量不做限制;
  • 如果实际执行的SQL需要对某数据库实例中的200张表做操作,则对每张表创建一个新的数据库连接,并通过多线程的方式并发处理,以达成执行效率最大化。
  • 在SQL满足条件情况下,优先选择流式归并,以防止出现内存溢出或避免频繁垃圾回收情况。
连接限制模式
  • 使用此模式的前提是,Sharding-JDBC 严格控制对一次操作所耗费的数据库连接数量。
  • 如果实际执行的SQL需要对某数据库实例中的200张表做操作,那么只会创建唯一的数据库连接,并对其200张表串行处理。
  • 如果一次操作中的分片散落在不同的数据库,仍然采用多线程处理对不同库的操作,但每个库的每次操作仍然只创建一个唯一的数据库连接。
  • 这样即可以防止对一次请求对数据库连接占用过多所带来的问题。该模式始终选择内存归并

内存限制模式适用于OLAP操作,可以通过放宽对数据库连接的限制提升系统吞吐量;
连接限制模式适用于OLTP操作,OLTP通常带有分片键,会路由到单一的分片,因此严格控制数据库连接,以保证在线系统数据库资源能够被更多的应用所使用,是明智的选择。

内存归并和流式归并的区别将在下一篇章介绍,敬请期待。

源码分析

将路由结果转换为 PreparedStatementUnit 列表
    public boolean execute() throws SQLException {
   
   
        try {
   
   
            // 获取路由映射 
            Collection<PreparedStatementUnit> preparedStatementUnits = route();
            // 2. 初始化 PreparedStatementExecutor 对象,并执行查询
            return new PreparedStatementExecutor(
                    getConnection().getShardingContext().getExecutorEngine(), routeResult.getSqlStatement().getType(), preparedStatementUnits).execute();
        } finally {
   
   
            JDBCShardingRefreshHandler.build(routeResult, connection).execute();
            clearBatch();
        }
    }

    private Collection<PreparedStatementUnit> route() throws SQLException {
   
   
        Collection<PreparedStatementUnit> result = new LinkedList<>();
        routeResult = routingEngine.route(getParameters());
        for (SQLExecutionUnit each : routeResult.getExecutionUnits()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值