【问题标题】:Best SQL query results storage最佳 SQL 查询结果存储
【发布时间】:2013-01-13 13:28:24
【问题描述】:

我将 SQL 查询的结果存储到 Arraylist<Hashtable<String, String>>,其中每个结果都存储在 Hashtable 中,然后每个结果都存储在列表中

如果结果少于 100.000 个,则它可以正常工作,如果我得到更多结果和 OutOfMemory 异常,则为 buf。

您对我如何改善这种情况有什么建议吗?

【问题讨论】:

  • 您真的需要一次获得所有结果吗?很可能您可以存储有限的数量,并在您真正需要它们时通过另一个查询提取更多。否则通常只是浪费内存。
  • 是的,我这样做了,因为我正在做的是从 JDBC 数据库表中获取信息并将其存储在 MongoDB 中,所以我需要存储所有信息
  • 我很困惑——你为什么不能把它作为一个多步骤的过程呢?如果您实际上是在另一个数据库上使用 SELECT 查询和 INSERT 查询,那么这是将其分开的完美候选者。无论如何,除非 JDBC 数据库表永远不会增长,否则您将不可避免地不得不这样做。即使您可以稍微提高存储效率,字符串也很大。你最终会耗尽内存。
  • 你能在 WHILE 循环中从记录集中一一读取记录并在该循环内保存到 MongoDB 中吗?
  • 你完全正确,克里斯。我没有想到那种情况。

标签: java sql arraylist hashtable


【解决方案1】:

您可以通过使用自定义类来表示每一行来节省一些空间。 (HashMap 是一种相当“消耗内存”的数据结构。)但是,这只会推迟不可避免的 OOME。

一个更好的主意是更改您的应用程序,这样您就不必将整个结果集存储在内存中。

【讨论】:

  • 自定义类不是一个选项,因为我不知道每个表的结果列。有很多桌子。
  • 但大概表格代表业务对象。每张桌子可以有一节课。诚然,可能有很多类,但代码更易于维护。
  • 如果自定义类不是一个选项,那么HashMap 是您的最佳选择。
【解决方案2】:

有几种不同的方法。 Stechen C 是正确的,最好在 SQL 中使用“where”子句来减小结果集的大小。

如果您使用缓存,您可以设置缓存的最大大小,最好的类是 LinkedHashMap。有一个 Map 的实现可以保持插入顺序。您需要对其进行子类化并覆盖 removeEldestEntry() 方法,如 Javadoc 中所示:

http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html#removeEldestEntry(java.util.Map.Entry)

【讨论】:

    【解决方案3】:

    改善这一点的最简单且可能占用内存最少的方法是为您的数据保留一个二维数组:

    String[][] data;
    
    // Alternatively, if you prefer lists:
    List<String[]> data;
    

    然后您只需要一个额外的数据结构,例如

    Map<String, Integer> fieldNameToIndexMapping;
    

    ...您将在其中存储查找表以按列索引访问您的字段。例如

    String value = data[row][fieldNameToIndexMapping.get("MY_COLUMN")];
    

    在适当的情况下,可以通过使用更简洁的数据类型进行更多调整。我怀疑您存储在数据结构中的一些String 值实际上是BooleanInteger 和其他更容易以非字符串形式存储的项目。

    【讨论】:

      猜你喜欢
      • 2014-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多