如何查找在 Oracle 中的 SQL 查询中返回的记录的内存大小?
How to find Memory SIZE of records returned in a SQL Query in Oracle?
我正在查询 returns 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 都可能创建您的数据或缓存的副本并重新使用它
- 查询可能 return 大小不同的结果,尤其是在使用 VARCHAR 等可变长度列类型时。您必须读取该数据才能确定相应 objects
的实际大小
- 一些 objects 可能被多个其他人引用,因此它们的大小可能被错误地包含(例如,如果使用了一些枚举常量,它可能被计入 object 大小但它不会实际上增加了增加,因为它很可能已经被加载了)。
此外,在大多数业务应用程序中,您无需费心确定一段代码所导致的确切内存消耗。同样有多种原因,例如:
- 内存很便宜,所以如果您 运行 遇到问题,通常(至少暂时)增加可用内存比(微)优化一段代码更容易。
- 由于情况不断变化(例如活跃用户数量、数据变化等),系统使用和负载通常无法预测
- JVM 通常能够高效地使用垃圾 collection 来为其他事情回收内存。
但这并不意味着您不应该考虑内存使用情况,例如你真的需要内存中的所有 10k 行吗?您需要这些数据多长时间以及您将如何处理这些数据?
话虽这么说,粗略估计内存消耗通常很有帮助,并且在查询可能 return 很多字符串的情况下,您应该估计最坏的情况,即假设最大长度的字符串。
为此,您需要了解行将包含的内容,例如整数 Integer
、Long
或 BigInteger
实例或可能有多少列。此外,您至少需要了解数据类型的内存要求,即我们不考虑 ResultSet
等的任何缓存、复制、开销等。
Java object 的大小取决于各种因素,例如您正在使用哪个 JVM,无论是 32 位还是 64 位 JVM 等。各种来源表明 object 的内存消耗可以从 Object header(通常规定为 12 个字节)和 object 字段的大小。
我们假设 Integer
的大小为 16 字节(12b header 和 4b int
),Date
将是 24 字节(12b header、8b fastTime
和 4b cdate
参考),字符串将是 12b header、4b char[] 参考、8b 其他字段、12h char[] header 和字符本身的 2*length 字节(或总共 36 + 2 * 长度)。
因此,假设您的 85 列被分成 20 个整数、10 个日期和 55 个最大长度为 256 字节的字符串。一行需要 至少 20 * 16 + 10 * 24 + 55 * 548 = 30700 字节。因此,10k 行需要 307000000 字节或大约 300 MB(当所有字符串都达到最大长度时)。
If I copy whole data and save it in file it shows only 604 KB for 10,000 records having 8 columns.
我们也把它分解一下:
- 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。
我正在查询 returns 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 都可能创建您的数据或缓存的副本并重新使用它
- 查询可能 return 大小不同的结果,尤其是在使用 VARCHAR 等可变长度列类型时。您必须读取该数据才能确定相应 objects 的实际大小
- 一些 objects 可能被多个其他人引用,因此它们的大小可能被错误地包含(例如,如果使用了一些枚举常量,它可能被计入 object 大小但它不会实际上增加了增加,因为它很可能已经被加载了)。
此外,在大多数业务应用程序中,您无需费心确定一段代码所导致的确切内存消耗。同样有多种原因,例如:
- 内存很便宜,所以如果您 运行 遇到问题,通常(至少暂时)增加可用内存比(微)优化一段代码更容易。
- 由于情况不断变化(例如活跃用户数量、数据变化等),系统使用和负载通常无法预测
- JVM 通常能够高效地使用垃圾 collection 来为其他事情回收内存。
但这并不意味着您不应该考虑内存使用情况,例如你真的需要内存中的所有 10k 行吗?您需要这些数据多长时间以及您将如何处理这些数据?
话虽这么说,粗略估计内存消耗通常很有帮助,并且在查询可能 return 很多字符串的情况下,您应该估计最坏的情况,即假设最大长度的字符串。
为此,您需要了解行将包含的内容,例如整数 Integer
、Long
或 BigInteger
实例或可能有多少列。此外,您至少需要了解数据类型的内存要求,即我们不考虑 ResultSet
等的任何缓存、复制、开销等。
Java object 的大小取决于各种因素,例如您正在使用哪个 JVM,无论是 32 位还是 64 位 JVM 等。各种来源表明 object 的内存消耗可以从 Object header(通常规定为 12 个字节)和 object 字段的大小。
我们假设 Integer
的大小为 16 字节(12b header 和 4b int
),Date
将是 24 字节(12b header、8b fastTime
和 4b cdate
参考),字符串将是 12b header、4b char[] 参考、8b 其他字段、12h char[] header 和字符本身的 2*length 字节(或总共 36 + 2 * 长度)。
因此,假设您的 85 列被分成 20 个整数、10 个日期和 55 个最大长度为 256 字节的字符串。一行需要 至少 20 * 16 + 10 * 24 + 55 * 548 = 30700 字节。因此,10k 行需要 307000000 字节或大约 300 MB(当所有字符串都达到最大长度时)。
If I copy whole data and save it in file it shows only 604 KB for 10,000 records having 8 columns.
我们也把它分解一下:
- 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。