【性能优化】4.4 [遍历技术] 数据库并行加载

 

【性能优化】4.3 [遍历技术] 并行遍历

4.4 数据库并行加载

有时我们需要从数据库中读出数据进行复杂运算,常常会发现数据库负载并不重的时候,读出数据的时间却很长。这主要是由于数据库的访问接口性能较差导致的,使用并行可以有效地缓解这个问题。


A

B

1

fork to(4)

=connect(…)

2


=range(MinID,MaxID+1,A1:4)

3


=B1.query("select * from T where id>=? and id<?,B2(1),B2(2))

4


>B1.close()

5

=A1.conj()

这段代码将并行取出 T 表中 id 值在 MinID 和 MaxID 范围之间的记录。将条件区间拆分成多段,每个线程取其中一段。注意数据库需要在每个线程内单独连接,否则数据库会强制同一个连接的请求串行执行,并行逻辑就无法实现了。

数据库没有接口实现分段拆分,只能使用 where 来拆分,可以根据对数据特征的了解使用更合理的拆分方案。where 计算会占用数据库资源,并行取数只能在数据库资源不紧张时应用(取数慢是由于接口慢而不是数据库计算慢),太复杂的 where 计算也会造成并行取数的效果变差。

如果取出数据量大要使用数据库游标,那要在每个线程内处理读出来的数据,才能起到并行的效果,不能在线程中返回延迟游标而没有实质计算。


A

B

1

fork to(4)

=connect(…)

2


=range(MinID,MaxID+1,A1:4)

3


=B1.cursor("select * from T where id>=? and id<?,B2(1),B2(2))

4


=B3.groups(…)

5

=A1.conj().groups(…)

使用多个不同 SQL 取数时也可以使用并行方案:


A

B

1

=["select …","select…",…]

2

fork A1

=connect(…)

3


=B2.query(A2)

4


>B2.close()




多个 SQL 时可以使用更大的一些并行线程数,不同 SQL 执行速度不同,即使物理上没有更多的线程数,也能起到平衡负载的作用。有线程分配到可较快执行的 SQL 时,可以执行更多任务,以避免线程等待。

【性能优化】4.5 [遍历技术] 多路游标

【性能优化】 前言及目录