【问题标题】:What is maximum rows count in oracles nested tableoracle嵌套表中的最大行数是多少
【发布时间】:2014-08-03 04:23:39
【问题描述】:
CREATE TYPE nums_list AS TABLE OF NUMBER;

oracle 的嵌套表中的最大可能行数是多少?

更新

CREATE TYPE nums_list  AS TABLE OF NUMBER;

CREATE OR REPLACE  FUNCTION  generate_series(from_n NUMBER, to_n NUMBER)
RETURN nums_list AS
ret_table nums_list := nums_list();
BEGIN

  FOR i IN from_n..to_n LOOP
    ret_table.EXTEND;
    ret_table(i) := i;
  END LOOP;
  RETURN ret_table;

END;


SELECT count(*)   FROM TABLE ( generate_series(1,4555555) );

这会产生错误:ORA-22813 operand value exceeds system limits, Object or Collection value was too large

【问题讨论】:

  • 为什么不使用流水线函数呢?我猜你正在达到内存限制而不是“最大行数”限制 - 使用这样的集合意味着,所有数字都需要保存在内存中。
  • 很好的建议,非常感谢

标签: sql database oracle oracle12c nested-table


【解决方案1】:

range of subscripts for a nested table is 1..2**31,因此您可以在集合中拥有 2**31 个元素。这个限制至少从 8.1.6 开始就没有改变,当然,它将来可能会改变。

【讨论】:

  • 贾斯汀,他们在 11g 中增加了它significantly higher?
  • @OracleUser - 表示 2147483647,即 2**31 - 1 - 所以它没有改变?
  • 其实亚历克斯我应该承认,我假设 2**31 是一个五位数。那么它是 2^31 吗?
  • @OTARIKI - 在这种情况下,** 的含义与^ 相同,即限制为 2 的 31 次方减去 1,即 2147483647。后来的文档(如 OracleUser 链接to) 显示实际数字,可能是为了避免这种混淆......
  • @OTARIKI - 2**31 只是 2^31 的另一种表示法(2 次方的 31 次方),计算结果略高于 20 亿。
【解决方案2】:

作为一个额外的观察,不是嵌套表本身太大或使用太多内存。使用异常处理程序,您可以看到您的函数没有抛出错误。您可以在匿名块中填充相同的内容:

DECLARE
  ret_table nums_list := nums_list();
BEGIN
  FOR i IN 1..4555555 LOOP
    ret_table.EXTEND;
    ret_table(i) := i;
  END LOOP;
  dbms_output.put_line(ret_table.count);
END;
/

anonymous block completed
4555555

你也可以从一个块中调用你的函数:

DECLARE
  ret_table nums_list;
BEGIN
  ret_table := generate_series(1,4555555);
  dbms_output.put_line(ret_table.count);
END;
/

anonymous block completed
4555555

只有当你使用它作为表集合表达式时才会报错:

SQL Error: ORA-22813: operand value exceeds system limits
22813. 00000 -  "operand value exceeds system limits"
*Cause:    Object or Collection value was too large. The size of the value
           might have exceeded 30k in a SORT context, or the size might be
           too big for available memory.
*Action:   Choose another value and retry the operation.

cause 文本指的是 SORT 上下文,并且您的查询正在进行排序:

------------------------------------------------------------------------------------------------------
| Id  | Operation                          | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                   |                 |     1 |     2 |    29   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE                    |                 |     1 |     2 |            |          |
|   2 |   COLLECTION ITERATOR PICKLER FETCH| GENERATE_SERIES |  8168 | 16336 |    29   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------

正如@a_horse_with_no_name 建议的那样,您可以通过使函数流水线化来避免该问题:

CREATE OR REPLACE  FUNCTION  generate_series(from_n NUMBER, to_n NUMBER)
RETURN nums_list PIPELINED AS
BEGIN

  FOR i IN from_n..to_n LOOP
    PIPE ROW (i);
  END LOOP;
  RETURN;

END;
/

SELECT count(*)   FROM TABLE ( generate_series(1,4555555) );

  COUNT(*)
----------
   4555555 

SORT AGGREGATE 仍然有效,但它似乎不再介意。不太确定为什么在这两种情况下都会这样做;也许其他人将能够解释它在做什么。 (顺便说一句,我在 11gR2 实例中执行此操作;我没有 12c 实例来验证行为是否相同,但您的症状表明会如此)。或者,问题可能不是 SORT 上下文,而是可用内存。在我的环境中,您的版本似乎始终可以使用多达 4177918 个元素 - 这似乎不是一个重要的数字,因此可能与环境有关?

但这取决于您打算如何使用该集合;从 PL/SQL 上下文来看,您的原始版本可能更合适。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-29
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-16
    相关资源
    最近更新 更多