【问题标题】:the faster way to extract all records from oracle从 oracle 中提取所有记录的更快方法
【发布时间】:2020-03-05 22:29:25
【问题描述】:

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

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

select /+ 8 parallel +/
* from table

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

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

【问题讨论】:

  • “需要 30 分钟才能获得 1 亿条记录” 得到它 查询时间有多少,跨网络传输和客户端渲染有多少?数据库查询优化都是关于细节的。没有简单的启发式方法可以解决所有问题。请阅读this post on asking Oracle tuning questions。我解释了在我们尝试回答之前您需要提供的信息,尽管我们可以说索引不会帮助您加快全表读取。
  • 我将它们提取到文件中,我如何计算跨网络传输和在客户端呈现的时间?我使用 jdbc Scala 库来提取数据

标签: sql oracle performance query-optimization bulk-operations


【解决方案1】:

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

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

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

select * from table partition (p1);
select * from table partition (p2);
...

【讨论】:

  • 使用你提到的partions,我可以在20分钟内获得4.55亿:)谢谢
【解决方案2】:

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

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 2019-01-22
    • 2012-01-03
    • 2021-09-14
    • 2016-10-20
    • 1970-01-01
    相关资源
    最近更新 更多