如何找出 select 查询的最佳提取大小

How to figure out the optimal fetch size for the select query

在 JDBC 中,默认提取大小为 10,但我想当我有一百万行时,这不是最佳提取大小。我知道获取大小太低会降低性能,如果获取大小太高也会降低性能。

如何找到最佳尺寸?这对数据库端有影响吗,它会消耗大量内存吗?

与(几乎)任何事物一样,为特定参数找到最佳大小的方法是对您尝试使用不同参数值优化的工作负载进行基准测试。在这种情况下,您需要 运行 您的代码具有不同的提取大小设置、评估结果并选择最佳设置。

在绝大多数情况下,人们会选择 100 或 1000 的提取大小,事实证明这是一个合理的最佳设置。此时值之间的性能差异通常非常小——您会认为 运行 之间的大部分性能差异是正常随机变化的结果,而不是由获取大小的变化引起的。如果您试图获得特定配置中特定工作负载的最后一点性能,您当然可以进行该分析。不过,对于大多数人来说,100 或 1000 就足够了。

如果您的行很大,请记住您一次获取的所有行都必须存储在驱动程序内部缓冲区的 Java 堆中。在 12c 中,Oracle 有 VARCHAR(32k) 列,如果您有 50 个列并且它们已满,则每行 1,600,000 个字符。 Java中每个字符占2个字节。所以每一行最多可以占用 3.2MB。如果您要获取 100 行 100 行,那么您将需要 320MB 的堆来存储数据,而这只是一个语句。因此,您应该只为获取相当小的行(数据量小)的查询增加行预取大小。

JDBC 的默认预取大小为 10。查看 OracleConnection.getDefaultRowPrefetch 在 JDBC Javadoc

JDBC 获取大小 属性 的默认值是 特定于驱动程序的 而对于 Oracle 驱动程序,它确实是 10。

对于某些查询,获取大小应该较大,对于某些较小。

我认为一个好主意是为整个项目设置一些 global 获取大小,并为某些 overwrite个别查询 应该更大。

看这篇文章:

http://makejavafaster.blogspot.com/2015/06/jdbc-fetch-size-performance.html

描述了如何全局设置获取大小并使用不同方法为精心选择的查询覆盖它:Hibernate、JPA、Spring jdbc 模板或核心 jdbc API。还有一些简单的 Oracle 数据库基准测试。

根据经验,您可以:

  • 将 fetchsize 设置为 50 - 100 作为全局设置
  • 将单个查询的 fetchsize 设置为 100 - 500(或更多)