猿问

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

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

SELECT * FROM employee WHERE id < 11000;

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

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

需求:实际上我需要加载内存中的所有记录;对于这些记录在Java中进行一些处理。所以我需要使用Oracle中的一些先决条件来检查数据的大小,或者您可以建议检查相同的任何其他适当的方法吗?(我有生产访问权限。所以我将在检查数据大小后实现逻辑)。

这个预检查只是为了避免java中出现内存不足异常。

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


千万里不及你
浏览 132回答 1
1回答

四季花海

通常,您可以使用 Java 的检测功能来确定运行时的内存消耗。然而,由于各种原因,确定实际内存消耗并不总是那么容易,其中一些原因是:框架、库甚至 JVM 可能会创建数据或缓存的副本并重用它查询可能返回不同大小的结果,尤其是在使用 VARCHAR 等可变长度列类型时。您必须读取该数据才能确定相应对象的实际大小某些对象可能被多个其他对象引用,因此它们的大小可能会被错误地包含在内(例如,如果使用某些枚举常量,则可能会计入对象大小,但它实际上不会增加增量,因为它很可能已经被加载) 。此外,在大多数业务应用程序中,您无需费心确定一段代码导致的确切内存消耗。原因也有多种,例如:内存很便宜,因此如果遇到问题,(至少暂时)增加可用内存通常比(微)优化一段代码更容易。由于情况的变化(例如活跃用户数量、数据变化等),系统使用和负载通常无法预测。JVM 通常能够有效地使用垃圾收集来回收内存以用于其他用途。但这并不意味着您不应该考虑内存使用情况,例如,您真的需要同时在内存中存储所有 10k 行吗?您需要这些数据多长时间?您将如何处理这些数据?话虽如此,粗略估计内存消耗通常很有帮助,并且在可能返回大量字符串的查询的情况下,您应该估计最坏的情况,即假设最大长度字符串。为此,您需要了解行将包含的内容,例如是否是整数、Integer实例或可能有多少列。此外,您至少需要知道数据类型的内存要求,即我们不考虑任何缓存、重复、开销等。LongBigIntegerResultSetJava 对象的大小取决于多种因素,例如您使用的是哪个 JVM,是 32 位还是 64 位 JVM 等。各种来源表明,对象的内存消耗可以从对象标头(通常是大小为 12 个字节)和对象字段的大小。使用它,我们假设Integer大小为 16 字节(12b 标头和 4b int),Date将是 24 字节(12b 标头,8bfastTime和 4bcdate引用),字符串将是 12b 标头,4b char[] 引用,8b 其他字段, 12h char[] 标头和字符本身的 2*length 字节(或总共 36 + 2* 长度)。因此,假设您的 85 列被分成 20 个整数、10 个日期和 55 个最大长度为 256 字节的字符串。一行至少需要20 * 16 + 10 * 24 + 55 * 548 = 30700 字节。因此,10k 行需要 307000000 字节或大约 300 MB(当所有字符串都达到最大长度时)。如果我复制整个数据并将其保存在文件中,对于 8 列的 10,000 条记录,它仅显示 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。
随时随地看视频慕课网APP

相关分类

Java
我要回答