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() | / 合并查询结果 |
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);
}
}
}
}