【问题标题】:Fast Oracle Select [Huge Data]Fast Oracle Select [海量数据]
【发布时间】:2011-01-21 00:36:04
【问题描述】:

我有一个项目,我通过 Java 从 Oracle 数据库中读取大量数据。

我感觉我们正在编写的应用程序处理数据的速度比使用单线程 SELECT 查询提供给我们的速度要快得多,因此我一直在尝试研究更快获取数据的方法。

有没有人可以阅读可以帮助我解决困境的任何内容?

【问题讨论】:

  • 定义巨大的。多少行?每行多少字节?您正在读取 LONG、BLOB 或 CLOB 数据吗?是否涉及复杂的连接?消费者应用程序处理数据的速度有多快?您是否真的遇到了困境,或者您正在担心一个不存在的问题?

标签: java oracle select jdbc performance


【解决方案1】:

首先,对于数据库人员来说,“海量数据”是 [至少] GB,在这种情况下,我怀疑您的问题是将这些卷读入您的进程内存并在那里聚合它们。为什么你认为单线程选择会成为瓶颈?

如果瓶颈是从磁盘获取数据,那么让多个线程从同一个磁盘提取数据不一定会更快,甚至可能会更慢。但是,如果您可以将数据分布在单独的磁盘上,那么单独的线程会更快。如果使用 SSD,您认为磁盘不会成为争论点,我们可以看看其他地方。

如果瓶颈是网络带宽,那么多个线程将无法更快地通过管道容纳更多数据。您甚至可以从将数据卸载到平面文件、对其进行压缩和传输中受益。

如果选择正在排序或来自散列连接,则可以通过单个线程更有效地使用内存。多个会话必须共享机器的内存。

如果有一个 CPU 密集型处理,那么多线程可能会有所帮助。这可能就像从 java 获得多个连接一样简单,每个连接都获得不同的数据片段(例如 A-K 和 L-Z),但这在很大程度上取决于 SELECT。

我同意 dpbradley 的观点,即您应该首先确定瓶颈。如果你有数据并选择,它应该足够简单来确定它需要多长时间(在本地机器上和通过网络),并且跟踪将是真正进入如何加速它的必要起点.

【讨论】:

  • 对不起,我应该说,它更像是 TB 级的数据。不过,您在从磁盘中提取数据方面很有意义,好点。 thx,在多线程方面很有意义。
  • 如果您要转移 TB,我会考虑通过网络进行压缩。有效性将取决于它是冗长的(例如 XML)还是已经压缩的(视频文件)。我怀疑网络早在数据库之前就会成为一个节流阀。
  • 好吧,很高兴知道,我们的服务器有可能与数据库在同一个盒子上,但这有点不太可能。
【解决方案2】:

Oracle 支持parallel DML。这尤其适用于 SELECT 查询。最终瓶颈可能是 IO 读取速度。要么使用速度更快的磁盘,要么跨多个磁盘条带化数据。

更新

在 cmets Parallel Queries/DML 中指出 APCEntreprise Edition feature,在标准版中不可用。

此外,Parallel DML/Query 并不是所有性能问题的解决方案。由于查询将使用多个进程,因此它可能会提高吞吐量,但会以并发为代价。并行的目的是使用更多的资源来更快地处理查询。如果查询是 IO-bound 或 CPU-bound,则没有额外的资源可以使用,添加并行只会让事情变得更糟。

从上面的链接:

并行执行不正常 有用的:

  • CPU、内存或 I/O 资源已在其中的环境 大量使用。并行执行 旨在利用额外的 可用的硬件资源;如果不 有这样的资源,那么 并行执行不会产生任何 好处,实际上可能是有害的 性能。

【讨论】:

  • 或者,如果输出少于您选择的所有数据,请查看在 Oracle 数据库中运行的存储过程(PL/SQL 或 Java)
  • 并行查询也会受到 CPU 的限制。也就是说,如果我们服务器的 CPU 已经用尽,我们将无法从 PQ 中获得任何好处。事实上,这可能会让事情变得更糟。
  • 通常的警告也适用于许可。并行查询是企业版功能。
  • 我认为 CPU 的数量或磁盘的速度不会成为问题。我不太担心这一点,因为我知道数据库正在运行固态磁盘。读取多线程似乎是最好的方法,因此我们可以尽可能多地使用盒子并尽可能快地将内容读入我们的应用程序。
  • @APC:当然,我更新了我的答案以添加必要的警告。
【解决方案3】:

在打开查询之前,对 Statement 或 PreparedStatement 使用 setFetchSize(int) 方法。您应该尝试不同的尺寸。尝试 75 作为起点。

在稍微不同的用法上,人们说 PL/SQL 批量获取“最佳位置”在 2000 到 3000 之间,但我看到一个基准表明 75 是最佳值。

较大的获取大小将倾向于减少客户端和服务器之间的往返次数。但如果它太大,数据库必须有一个很大的缓冲区,并且网络软件可能不得不将大消息分解成很多数据包。

【讨论】:

  • 我会非常怀疑 any 数字是否是“最佳位置”,它可能过多地取决于许多因素,包括每行的大小,也许甚至网络传输层的性质。最后最好选择一个起点,用有代表性的数据量进行性能测试。
  • 没错,我应该添加“您的里程可能会有所不同”或类似的免责声明。请注意,我抛出了 75 到 3000 之间的数字,这是一个相当大的范围。我的猜测是,高于 75 的性能提升(如果有的话)将变得非常小。但这只是一个猜测。我的第二个猜测是,一个人很容易浪费更多的时间来测试多个场景,这些场景将被保存以试图获得最后纳秒的性能。但同样,这取决于情况......让我印象深刻的一件事是,最初的问题假设在他们尝试任何具体的事情之前就会出现问题......
【解决方案4】:

您没有向我们提供很多信息,说明为什么有必要将“大量数据”引入 Java 应用程序而不是在数据库端进行处理。虽然可能有例外,但通常这是重新思考设计的信号。作为 Oracle 的一般规则,使用纯集合操作 (SQL) 完成尽可能多的工作是最有效的,然后使用 rdbms 引擎 (PL/SQL) 进行过程处理,然后再将结果返回到客户端应用程序。

【讨论】:

  • 不幸的是,由于我们系统的性质,我们需要其中的所有信息才能进行任何处理(聚合许多不同系统的数据价值,而不是全部来自 oracle)。我当然会考虑使用存储过程进行一些处理,但我必须读取大部分数据。
  • @PintSizedCat - 好的,听起来有点特殊,但您应该做一些测试以表明 Oracle 结果集传输将成为实际瓶颈,然后再进一步。
  • @PintSizedCat:你证明瓶颈在哪里了吗?您是否运行了包含在 DBMS_MONITOR.SESSION_TRACE_ENABLE() 和 DBMS_MONITOR.SESSION_TRACE_DISABLE() 调用中的 SQL 以获取等待信息?您是有意还是无意地对数据进行排序?
  • 我还没有,我想通过学习一点关于 oracle 的知识以及我如何能够做到这一点,从而快速开始这个项目。我们明天开始。我会按照你们俩所说的去做,看看我们是否遇到了 oracle 的瓶颈。
猜你喜欢
  • 2019-02-06
  • 1970-01-01
  • 2014-06-13
  • 1970-01-01
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多