SQL 如何实现单表分段并行取数

在查询表数据时,如果记录的顺序对计算结果没有影响,则可以用多线程并行读取,从而更充分地利用系统资源,以达到提高效率的目的。

基于单表(单 SQL)并行取数前需要进行数据分段,尽量保证每个分段的数据量平均。分段参数尽量基于索引字段(如会员编号),数据量较大时效率明显提高。

下面按照索引字段会员编号 ID 进行分段,查询会员数据。

SQL 语句类似于:

select * from MEMBER where ID<=1000000;
select * from MEMBER where ID>1000000 and ID<= 2000000;

select * from MEMBER where ID>2000000 and ID<= 3000000;

集算器编写脚本demo.dfx

A B C
1 =connect("mysql") / 连接数据库
2 =A1.query@x("select max(ID) tmax, min(ID) tmin from   MEMBER") / 查询 ID 最大值与最小值
3 >b=A2.tmin >e=A2.tmax+1 / 计算 ID 的端点
4 >p=4 =range(b, e+1, p) / 将 ID 按范围分成 4 段
5 =B4.to(,p) =B4.to(2,) / 分段参数初值与终值
6 fork A5, B5 =connect("mysql") /fork 启动多个 (4 个) 线程
7 =B6.query@x("select * from MEMBER where   ID>=? and ID<?", A6(1), A6(2)) / 线程中分段查询
8 =A6.conj() / 合并查询结果
 1.      执行脚本返回结果:
A8 ID NAME GENDER
100 Emily F
101 Samantha F
... ... ...
各线程提取本段数据,最后合并数据。

Java中调用这段脚本:
public
static void doWork() {
    Connection con = null;
    java.sql.Statement st;
    try{
        Class.forName("com.esproc.jdbc.InternalDriver");
        con = DriverManager.getConnection("jdbc:esproc:local://"); 
        // 调用脚本 demo.dfx
        st=con.createStatement(); 
        ResultSet rst = st.executeQuery("call demo");
       System.out.println(rst);
    }catch(Exception e){
        System.out.println(e);
    }finally{
        // 关闭连接
        if (con!=null) {
            try {
                con.close();
            }catch(Exception e) {
                System.out.println(e);
            }
        }  
    }
}