如果我有一个包含三列的表,
NAME (VARCHAR2 20), AGE (NUMBER), LOCATION (VARCHAR2 50)
在获取结果之前,Oracle JDBC驱动程序分配了多少内存?
如果fetch size
设置为100
,即使查询仅返回100
,驱动程序是否会为所有10
条记录分配内存?
由于
答案 0 :(得分:2)
Oracle数据库JDBC驱动程序,12之前的版本:
驱动程序在执行查询之前为每列分配最大大小乘以fetchSize
中的行数。
例如,对于VARCHAR(4000)
列,它将分配fetchSize
的8k字节。
版本12(及更高版本):
在执行查询之前,它在fetchSize
中每行每列分配大约15个字节。执行后,版本12中的驱动程序仅分配存储实际行数据所需的数量。
因此,版本12驱动程序通常使用的内存比早期版本少得多。驱动程序。
您的示例 :
在您的示例中,VARCHAR(20)
可以大到40个字节,NUMBER
可以大到22个字节,VARCHAR(100)
大到100个字节。将fetchSize
设置为100后,较旧的驱动程序将分配(40 + 22 + 100) * 100 = 16k
。版本12驱动程序将分配3 * 15 * 100 = 4.5k
。我忽略了两个驱动程序的额外开销。
答案 1 :(得分:0)
Oracle驱动程序分配fechtsize * max. size of one row
。
在你的情况下,这将是40个字节(= UTF-16中的20个字符)+ 22个字节+ 100个字节(= UTF-16中的100个字符)* 100.这总共大约16kb(可能更多一点) )
这实际上是驱动程序的唯一选择:如果您请求驱动程序通过网络发送100行,则必须分配足够的内存才能在内存中保存这100行。这意味着它必须假设最坏的情况并保留每列的最大长度。
一旦从服务器接收到数据,一旦将其转换为适当的Java对象,它将只占用所需的内存。
您可以设置提取大小以分配在检索操作期间使用的缓冲区。与例如类似一个BufferedInputStream
答案 2 :(得分:0)
您可以深入了解:http://www.oracle.com/technetwork/database/application-development/t-12c-1964666.pdf
正如您所看到的,它取决于JDBC驱动程序的版本,驱动程序配置(是否启用了准备语句缓存,您通过-D选项传递的参数)以及许多其他因素。
它甚至取决于您的应用程序中的其他SQL语句。
在最好的情况下,驱动程序不会分配任何内存,只是重用以前调用相同或不同语句的缓冲区(当然,取决于许多因素)。
在最糟糕的情况下,您将通过您已准备语句缓存中的其他SQL语句调用(对于Oracle JDBC< 11.2)分配获取数据所需的内存量