【问题标题】:SQL connection lifetimeSQL 连接生命周期
【发布时间】:2023-07-11 15:22:01
【问题描述】:

我正在开发一个 API 来查询数据库服务器(在我的例子中是 Oracle)以检索大量数据。 (这实际上是 JDBC 之上的一层。)

我创建的 API 试图尽可能限制将每个查询信息加载到内存中。我的意思是我更喜欢遍历结果集并逐一处理返回的行,而不是将每一行加载到内存中并稍后处理。

但我想知道这是否是最佳做法,因为它存在一些问题:

  • 在整个处理过程中会保留结果集,如果处理时间与检索数据一样长,则意味着我的结果集将打开两倍的时间
  • 在我的处理循环中执行另一个查询意味着打开另一个结果集,而我已经在使用一个结果集,同时开始打开太多结果集可能不是一个好主意。

另一方面,它有一些优点:

  • 我的结果集在内存中的数据永远不会超过一行,因为我的查询往往会返回大约 100k 行,这可能是值得的。
  • 由于我的框架主要基于函数式编程概念,因此我从不依赖多个行同时在内存中。
  • 在数据库引擎仍在返回其他行的同时开始处理返回的第一行可以极大地提高性能。

作为对甘道夫的回应,我补充一些信息:

  • 我总是需要处理整个结果集
  • 我没有对行进行任何聚合

我正在与主数据管理应用程序集成并检索数据,以验证它们或使用多种不同格式(到 ERP、Web 平台等)导出它们

【问题讨论】:

  • “SQL server (Oracle)”是什么意思?
  • 试图澄清,很抱歉造成混乱
  • 为了权衡好处,我们确实需要更多地了解您如何使用查询结果。你会一直处理整个结果集吗?您是将每个结果的值加在一起,还是可以在数据库端完成的任何其他聚合工作?

标签: sql oracle jdbc memory-management master-data-management


【解决方案1】:

没有普遍的答案。我亲自实施了这两种解决方案数十次。

这取决于对您来说更重要的因素:内存或网络流量。

如果您有快速的网络连接 (LAN) 和较差的客户端计算机,则从服务器逐行获取数据。

如果您在Internet 上工作,那么批量提取将帮助您。

您可以设置预取计数或数据库层属性并找到一个中庸之道。

经验法则是:在不注意的情况下获取所有可以保留的东西

如果您需要更详细的分析,则涉及六个因素:

  • 行生成响应时间/速率Oracle 多快生成第一行/最后一行)
  • 行交付响应时间/速率(多久可以得到第一行/最后一行)
  • 行处理响应时间/速率(多久可以显示第一行/最后一行)

其中一个将成为瓶颈。

通常,rateresponce time 是对立的。

通过预取,您可以控制行传递响应时间行传递率:较高的预取计数会提高速率但会缩短响应时间,较低的预取计数会对面。

选择对您更重要的一项。

您还可以执行以下操作:为获取和处理创建单独的线程。

在低预取模式下(响应时间长)只选择足够多的行让用户感到愉快,然后切换到高预取模式。

它将在后台获取行,您也可以在后台处理它们,同时用户浏览第一行。

【讨论】:

  • 根据您的经验,我知道如果我有无限量的内存,我应该一次获取每条记录。但我对这个选项的问题是获取 100k 记录需要时间,并且会延迟这些记录的处理开始。一个一个地获取它们允许我在获取记录时开始处理并限制 CPU 使用率,因为我的处理实际上发生在每个记录获取之间。
  • 感谢您提出分析建议。我将分析这些价值观并尝试做出最佳决定。也感谢您的建议,但我的应用程序不是面向用户的 bue 面向数据的,我需要尽快导出尽可能多的数据。