java - 如何查找Oracle中SQL查询中返回的记录的内存大小?

标签 java sql oracle size heap-memory

我正在查询一个返回10,000条记录的查询。

SELECT * FROM employee WHERE id < 11000;


返回的数据由85列(varchar,日期,编号)组成。
(此外,我还有另一个类似的查询获取的数据仅由10列(varchar)组成。)

Oracle中有什么方法可以找到此结果集的数据大小?像加载的数据将是100 MB或200 MB

要求:实际上我需要将所有记录加载到内存中;这些记录以便在Java中进行某些处理。因此,我需要使用Oracle中的某些前提条件来检查数据大小,或者您可以建议使用其他任何合适的方式来检查数据大小? (我具有生产访问权限。因此,我将在检查数据大小之后实施逻辑)。

此预检查只是为了避免Java中的内存不足异常。

如果我复制整个数据并将其保存在文件中,则10,000条具有8列的记录仅显示604 KB。内存中是否也一样?

最佳答案

通常,您可以使用Java的工具功能来确定运行时的内存消耗。有关此的一些信息,请在这里查看:


In Java, what is the best way to determine the size of an object?
https://www.baeldung.com/java-size-of-object


但是,由于各种原因,确定实际的内存消耗并不总是那么容易,其中一些原因是:


框架,库甚至JVM可能会创建数据或缓存的副本并重用它
查询可能会返回不同大小的结果,尤其是在使用可变长度列类型(如VARCHAR)时。您必须读取该数据以确定相应对象的实际大小
有些对象可能被多个其他对象引用,因此它们的大小可能不正确地包含在内(例如,如果使用了某些枚举常量,则该对象常量可能会计入对象大小,但实际上并不会增加该增量,因为无论如何它很可能已被加载) 。


此外,在大多数业务应用程序中,您无需费心确定代码导致的确切内存消耗。同样,有多种原因,例如:


内存很便宜,因此如果遇到问题,(至少(暂时))增加可用内存通常比(微)优化一段代码要容易得多。
由于情况的变化(例如活动用户数,数据更改等),系统使用率和负载通常无法预测
JVM通常能够有效地使用垃圾回收来为其他事情回收内存。


但这并不意味着您不应该考虑内存使用情况,例如您真的需要一次将所有这1万行存储在内存中吗?您需要多长时间该数据,您将如何处理?

话虽如此,粗略估计内存消耗通常是有帮助的,如果查询可能返回很多字符串,则应该估计最坏的情况,即假设最大长度的字符串。

为此,您需要一些有关行将包含的内容的知识,例如整数IntegerLongBigInteger实例,或可能有多少列。此外,您至少需要了解数据类型的内存要求,即我们不考虑任何缓存,重复,ResultSet的开销等。

Java对象的大小取决于各种因素,例如您正在使用哪个JVM,无论是32位还是64位JVM等。各种来源都指出,可以从Object标头(通常称其为12个字节)中计算对象的内存消耗。对象的字段。

假设Integer的大小为16个字节(12b标头和4b int),Date为24字节(12b标头,8b fastTime和4b cdate引用),字符串将是12b标头,4b char []引用,8b其他字段,12h char []标头和2 * length个字节(用于字符本身)(或总计36 + 2 *个长度)。

因此,假设您的85列分为20个整数,10个日期和55个最大长度为256个字节的字符串。一行至少需要20 * 16 + 10 * 24 + 55 * 548 = 30700字节。 1万行因此需要307000000字节或大约300 MB(当所有字符串都处于最大长度时)。


  如果我复制整个数据并将其保存在文件中,那么对于10,000条具有8列的记录,它仅显示604 KB。


让我们也分解一下:


604 KB将为618496字节(1024为1 KB)
将其相差10k,平均每行可获得61.8字节
将该数字除以8,就可以得到每列7.7个字节(如果我们不考虑任何行或列分隔符的话)
让我们将其四舍五入为每列8个字节,并假设您的文本文件是Latin-1编码的(因此每个字符1个字节),因此每个文本列平均有8个字符,这很短


在更简单的计算中,如果我们使用与上述相同的假设,则604KB将意味着您的数据将由大约604k个字符组成,在Java中,仅就字符数据而言,将需要1208k字节(或约1.2 MB)。加上80k字符串的开销,即36字节* 80k,这大约是2.8 MB,因此数据将需要大约4 MB的内存。

关于java - 如何查找Oracle中SQL查询中返回的记录的内存大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58553553/

相关文章:

sql - 更改 Excel 连接中的 SQL 命令

.net - ODP.NET 可以重新分发吗?

java - 如何在 OpenTest 中开始新的测试 session ?

java - 使用 WSDL 从 url 和身份验证实例化 JAX-WS 服务

java - debian apt 找不到 openjdk-8-jdk

oracle - SQLplus解码执行脚本

sql - Oracle SQL : Retrieving the value of adjacents fields if value is empty

java - 使用增强型 for 循环时的 IndexOutOfBoundsException

mysql - 简化 mySQL 查询

MySQL 查询已经 GROUPed 和 ORDERed : how to ORDER inside the GROUPs?