Verstehen Sie die Funktionalität der Statement.setFetchSize(nSize)-Methode im SQL Server-JDBC-Treiber
P粉463811100
2023-08-27 17:05:57
<p>Ich habe jeden Tag eine sehr große Tabelle mit Millionen von Datensätzen und am Ende jedes Tages rufe ich alle Datensätze vom Vortag ab. So mache ich es: </p>
<pre class="brush:php;toolbar:false;">String SQL = "select col1, col2, coln from mytable where timecol = today";
Statement.executeQuery(SQL);</pre>
<p>Das Problem besteht darin, dass dieses Programm etwa 2 GB Speicher benötigt, da es alle Ergebnisse im Speicher ablegt und sie dann verarbeitet. </p>
<p>Ich habe versucht, <code>Statement.setFetchSize(10)</code> festzulegen, aber es erhält genau den gleichen Speicher vom Betriebssystem, kein Unterschied. Ich verwende hierfür den <em>Microsoft SQL Server 2005 JDBC-Treiber</em> </p>
<p>Gibt es eine Möglichkeit, die Ergebnisse in kleinen Blöcken zu lesen, wie es der Oracle-Datenbanktreiber tut, wobei nur wenige Zeilen angezeigt werden, wenn die Abfrage ausgeführt wird, und mehr Ergebnisse angezeigt werden, wenn Sie nach unten scrollen? </p>
在 JDBC 中,
setFetchSize(int)
方法对于 JVM 内的性能和内存管理非常重要,因为它控制从 JVM 到数据库的网络调用数量以及相应的数据量。用于结果集处理的 RAM。本质上,如果调用 setFetchSize(10) 并且驱动程序忽略它,则可能只有两个选项:
RESULT-SET 是为响应查询而在数据库上编组的行数。 ROW-SET 是每次从 JVM 调用到 DB 时从 RESULT-SET 中提取的行块。 这些调用的数量以及处理所需的 RAM 取决于 fetch-size 设置。
因此,如果 RESULT-SET 有 100 行并且 fetch-size 为 10, 在任何给定时间,都会有 10 个网络调用来检索所有数据,使用大约 10*{row-content-size} RAM。
默认的 fetch-size 是 10,这个值相当小。 在发布的案例中,驱动程序似乎忽略了获取大小设置,在一次调用中检索所有数据(需要大量 RAM,最佳最小网络调用)。
在
ResultSet.next()
下发生的情况是,它实际上并没有从 RESULT-SET 中一次获取一行。它从(本地)ROW-SET 获取该数据,并在本地客户端上的数据耗尽时从服务器获取下一个 ROW-SET(不可见)。所有这些都取决于驱动程序,因为设置只是一个“提示”,但在实践中我发现这就是许多驱动程序和数据库的工作原理(在许多版本的 Oracle、DB2 和 MySQL 中得到验证)。 p>