使用 table 类型连接 tables 会减慢计算速度?
Joining tables with table type slows down calculation?
我有一个大型计算,将大约 10 tables 连接在一起,并从结果中计算出一些值。我想编写一个函数,允许我用我作为输入参数给出的 table (类型)替换连接的 table 之一(我们称之为 Table A) .
我已经为 table 一个赞
定义了行和 table 类型
create or replace TYPE t_tableA_row AS OBJECT(*All Columns of Table A*);
create or replace TYPE t_tableA_table as TABLE OF t_tableA_row;
我需要作为函数输出的计算类型也是如此。
我的函数看起来像这样
create or replace FUNCTION calculation_VarInput (varTableA t_tableA_table)
RETURN t_calculationResult_table AS
result_ t_calculationResult_table;
BEGIN
SELECT t_calculationResult_row (*All Columns of Calculation Result*)
BULK COLLECT INTO result_
FROM (*The calculation*)
RETURN result_;
END;
如果我使用仅使用 Table A(忽略输入参数)的正常计算来测试此函数,它工作正常,大约需要 3 秒。但是,如果我将 Table A 替换为 varTableA(输入参数是 Table A 的 table 类型),计算时间如此之长我从未见过它完成了。
当我使用 table A 进行计算时,它看起来像这样
/*Inside the calculation*/
*a bunch tables being joined*
JOIN TableA A On A.Value = B.SomeOtherValue
JOIN *some other tables*
当我使用 varTableA its
/*Inside the calculation*/
*a bunch tables being joined*
JOIN TABLE(varTableA ) A On A.Value = B.SomeOtherValue
JOIN *some other tables*
抱歉没有 post 确切的代码,但计算量很大,真的会膨胀这个 post。
知道为什么与使用实际 table 相比,在加入时使用 table 类型会使计算速度慢得多吗?
您的函数在函数中封装了一些选择逻辑,因此对优化器隐藏了信息。这可能会导致优化器做出错误或低效的决定。
Oracle 已经收集了 TableA
的统计信息,因此优化器知道它有多少行、索引了哪些列等等。因此它可以找出 table 的最佳访问路径。它没有 TABLE(varTableA )
的统计数据,因此它假设它将 return 8192
(即 8k)行。如果说原始 TableA
returned 8 行,这可能会更改执行计划。或 80000。您可以通过 .
轻松检查它
如果这是问题所在,请将 /*+ 基数 */ 添加到准确反映函数结果集中行数的查询中。提示(提示,不是函数)告诉优化器它应该在计算中使用的行数。
I don't want to actually change the values in my tables permanently, I just want to know what the calculation result would be if some values were different.
为什么不使用视图呢?从 TableA
中选择并在其投影中应用所需修改的简单视图。当然,我对您的数据以及您希望如何操作它一无所知,因此出于各种原因,这可能是不切实际的。但这是我要开始的地方。
我有一个大型计算,将大约 10 tables 连接在一起,并从结果中计算出一些值。我想编写一个函数,允许我用我作为输入参数给出的 table (类型)替换连接的 table 之一(我们称之为 Table A) .
我已经为 table 一个赞
定义了行和 table 类型create or replace TYPE t_tableA_row AS OBJECT(*All Columns of Table A*);
create or replace TYPE t_tableA_table as TABLE OF t_tableA_row;
我需要作为函数输出的计算类型也是如此。 我的函数看起来像这样
create or replace FUNCTION calculation_VarInput (varTableA t_tableA_table)
RETURN t_calculationResult_table AS
result_ t_calculationResult_table;
BEGIN
SELECT t_calculationResult_row (*All Columns of Calculation Result*)
BULK COLLECT INTO result_
FROM (*The calculation*)
RETURN result_;
END;
如果我使用仅使用 Table A(忽略输入参数)的正常计算来测试此函数,它工作正常,大约需要 3 秒。但是,如果我将 Table A 替换为 varTableA(输入参数是 Table A 的 table 类型),计算时间如此之长我从未见过它完成了。
当我使用 table A 进行计算时,它看起来像这样
/*Inside the calculation*/
*a bunch tables being joined*
JOIN TableA A On A.Value = B.SomeOtherValue
JOIN *some other tables*
当我使用 varTableA its
/*Inside the calculation*/
*a bunch tables being joined*
JOIN TABLE(varTableA ) A On A.Value = B.SomeOtherValue
JOIN *some other tables*
抱歉没有 post 确切的代码,但计算量很大,真的会膨胀这个 post。
知道为什么与使用实际 table 相比,在加入时使用 table 类型会使计算速度慢得多吗?
您的函数在函数中封装了一些选择逻辑,因此对优化器隐藏了信息。这可能会导致优化器做出错误或低效的决定。
Oracle 已经收集了 TableA
的统计信息,因此优化器知道它有多少行、索引了哪些列等等。因此它可以找出 table 的最佳访问路径。它没有 TABLE(varTableA )
的统计数据,因此它假设它将 return 8192
(即 8k)行。如果说原始 TableA
returned 8 行,这可能会更改执行计划。或 80000。您可以通过
如果这是问题所在,请将 /*+ 基数 */ 添加到准确反映函数结果集中行数的查询中。提示(提示,不是函数)告诉优化器它应该在计算中使用的行数。
I don't want to actually change the values in my tables permanently, I just want to know what the calculation result would be if some values were different.
为什么不使用视图呢?从 TableA
中选择并在其投影中应用所需修改的简单视图。当然,我对您的数据以及您希望如何操作它一无所知,因此出于各种原因,这可能是不切实际的。但这是我要开始的地方。