这个问题在setting cardinality for pipelined and table functions上得到了非常满意的回答,所以请去阅读全文!
总结:
方法:可扩展优化器
可扩展优化器由 Oracle Data Cartridge 实现(本质上是一种对象类型,称为接口类型,包含一个或多个定义明确的结构化方法)。此功能使我们能够设计自己的基数计算(作为接口类型中的规定方法),然后将它们与我们的表或流水线函数相关联。类型的基数方法由 CBO 在查询优化期间调用,以确定流水线或表函数的行数。
以下引用和示例来自文章,但在某种程度上适用于一致地回答问题。
1) 制作包装函数
我们将创建一个小函数来接收和返回我们的通用 VARCHAR2TABLE 类型的集合。这个函数对集合本身没有任何作用;它只是一个包装器。
SQL> CREATE FUNCTION card_varchar2(
2 p_collection IN varchar2table
3 ) RETURN varchar2table IS
4 BEGIN
5 RETURN p_collection;
6 END card_varchar2;
7 /
Function created.
2) 制作接口类型
其次,我们将创建一个与我们简单的 card_varchar2 函数相关联的接口类型规范,如下所示。
SQL> CREATE TYPE card_varchar2_ot AS OBJECT (
2
3 dummy_attribute NUMBER,
4
5 STATIC FUNCTION ODCIGetInterfaces (
6 p_interfaces OUT SYS.ODCIObjectList
7 ) RETURN NUMBER,
8
9 STATIC FUNCTION ODCIStatsTableFunction (
10 p_function IN SYS.ODCIFuncInfo,
11 p_stats OUT SYS.ODCITabFuncStats,
12 p_args IN SYS.ODCIArgDescList,
13 p_collection IN varchar2table
14 ) RETURN NUMBER
15
16 );
17 /
Type created.
和身体
SQL> CREATE TYPE BODY card_varchar2_ot AS
2
3 STATIC FUNCTION ODCIGetInterfaces (
4 p_interfaces OUT SYS.ODCIObjectList
5 ) RETURN NUMBER IS
6 BEGIN
7 p_interfaces := SYS.ODCIObjectList(
8 SYS.ODCIObject ('SYS', 'ODCISTATS2')
9 );
10 RETURN ODCIConst.success;
11 END ODCIGetInterfaces;
12
13 STATIC FUNCTION ODCIStatsTableFunction (
14 p_function IN SYS.ODCIFuncInfo,
15 p_stats OUT SYS.ODCITabFuncStats,
16 p_args IN SYS.ODCIArgDescList,
17 p_collection IN varchar2table
18 ) RETURN NUMBER IS
19 BEGIN
20 p_stats := SYS.ODCITabFuncStats(p_collection.COUNT);
21 RETURN ODCIConst.success;
22 END ODCIStatsTableFunction;
23
24 END;
25 /
Type body created.
3) 将函数与接口类型关联起来,如下。
SQL> ASSOCIATE STATISTICS WITH FUNCTIONS card_varchar2 USING card_varchar2_ot;
Statistics associated.
4) 现在像这样使用这个函数:
SQL> SELECT *
2 FROM TABLE(card_varchar2('A','B','C'));