有没有一个mysql JDBC会尊重fetchSize?

2022-09-02 03:22:46

我正在使用MySQL并希望利用该属性。默认的MySQL JDBC实现并不真正尊重它。如果你设置 fetchsize to it 将单独获取每一行,但考虑到我想使用 fetchSize 的原因是我有足够的数据将我的内存使用量放入 2 G 范围内,每行必须执行一个查询将永远花费。setFetchSizeInteger.MIN_VALUE

我想插入一个JDBC实现,它将与MySQL一起使用,并正确尊重抓取大小,允许我将抓取大小设置为10,000或其他更高的限制。任何人都可以指给我一个可以提供这种实现的jar吗?如果失败,是否有任何其他资源允许我以有效的方式合理地执行包含数万个条目的查询,但是在内存和所需的SQL查询数量上。


答案 1

如果你启用MySQL JDBC选项,fetchSize确实会被驱动程序尊重。useCursorFetch

但是,这种方法有一个缺点:它将使用服务器端游标,在MySQL中,游标是使用临时表实现的。这意味着在服务器上完成查询之前,结果不会到达,并且额外的内存将在服务器端使用。

如果您只想使用结果流,而不关心确切的提取大小,则开销并不像文档可能暗示的那样糟糕。它实际上只是禁用整个响应的客户端缓存,并在响应到达时为您提供响应;不需要每行往返。setFetchSize(Integer.MIN_VALUE)


答案 2

从技术上讲,询问库的问题是偏离主题的。也就是说,据我所知,MySQL没有其他驱动程序。您可以选择获取可能导致内存不足情况的所有行,也可以让驱动程序通过设置 来按需读取它们。setFetchSize(Integer.MIN_VALUE)

正如我从 Connector/J 实现注释中了解到的那样,这样做的原因是 MySQL 协议不能为每个连接打开多个游标,因此它默认在执行时将所有行流式传输到客户端。

另一个选项是逐个检索行,但这带来了一个问题,即在处理 :ResultSet

这种方法有一些警告。必须先读取结果集中的所有行(或将其关闭),然后才能对连接发出任何其他查询,否则将引发异常。

因此,MySQL只能选择获取所有内容或一次获取一个。这意味着驱动程序无法遵循不同的提取大小。由于逐个获取时的警告,他们选择使用(而不是简单地)作为信号,您应该在执行此操作之前真正思考。Integer.MIN_VALUE1

一个可能的“介于两者之间”的解决方案需要您自己使用并重复执行查询来编程。LIMITOFFSET


推荐