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

问题描述 投票:2回答:1

我正在查询一个返回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。内存中也一样吗?

java sql oracle size heap-memory
1个回答
0
投票

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

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

  • 框架,库甚至是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(当所有字符串都处于最大长度时)。

© www.soinside.com 2019 - 2024. All rights reserved.