0

我的 oracle 表包含 9 亿条记录,该表分区为 24 个分区,并且有索引:

我尝试使用提示并将 fetch_buffer 设置为100000

select /+ 8 parallel +/
* from table

获取1亿条记录需要30分钟

我的问题是:有没有更快的方法来获得 9 亿(表中的所有数据)?我应该使用分区并进行 24 个顺序查询吗?或者我应该使用索引并将我的查询拆分为 10 个查询,例如

4

2 回答 2

0

不是真正的答案,但评论太长了。

太多的变量可能会影响这一点,从而无法提供明智的建议,因此以下只是一些一般性提示。

这是通过网络还是服务器本地?如果数据库是远程服务器,那么您将付出沉重的网络代价。我建议(如果可能的话)使用 BEQUEATH 协议在服务器上运行提取,以避免使用网络。一旦文件完成,压缩和传输到目的地比通过 JDBC 行处理将数据直接从数据库传输到本地文件更快。

使用 JDBC 时,请记住设置游标提取大小以减少往返 - setFetchSize。默认值很小(我认为是 10),尝试 1000 之类的值,看看有什么帮助。

至于查询,您正在写入文件,因此即使 Oracle 可能会并行处理查询,您的写入文件过程可能不会,因此它是一个瓶颈。

我的方法是编写 Java 程序以将一系列值作为命令行参数进行操作,并尝试找出 Java 的哪些范围大小和并发实例可以提供最佳性能。范围可能会落在离散分区内,因此您将从分区修剪中受益(假设范围值是索引列,理想情况下是分区键)。

粗略地说,我会从 5m 的范围开始,并运行与 CPU 核心数相匹配的并发实例 - 2;这不是一个科学推导的数字,只是我倾向于将其用作我的第一次尝试,看看会发生什么。

于 2019-11-10T10:48:02.793 回答
0

网络几乎可以肯定是这里的瓶颈。Oracle 并行性仅影响数据库检索数据的方式,但数据仍通过单线程发送到客户端。

假设单个线程尚未使您的网络饱和,您可能需要构建一个并发检索解决方案。表已经分区,这样您就可以读取大块数据而无需重新读取任何内容。

我不确定如何在 Scala 中执行此操作,但您希望同时运行多个这样的查询,以使用所有可能的客户端和网络资源:

select * from table partition (p1);
select * from table partition (p2);
...
于 2019-11-09T22:07:07.910 回答