CREATE TABLE
COL1 CHAR(3)
,COL2 CHAR(17)
,COL3 NUMBER(7,0)
,COL4 CHAR(8)
,COL5 NUMBER(1,0)
)
PARTITION BY RANGE (COL4)
(
PARTITION PT_20200901 VALUES LESS THAN ('20200902'),
PARTITION PT_20200902 VALUES LESS THAN ('20200903'),
PARTITION PT_20200903 VALUES LESS THAN ('20200904'),
PARTITION PT_20200904 VALUES LESS THAN ('20200905'),
PARTITION PT_20200905 VALUES LESS THAN ('20200906'),
PARTITION PT_20200906 VALUES LESS THAN ('20200907'),
PARTITION PT_20200907 VALUES LESS THAN ('20200908'),
PARTITION PT_20200908 VALUES LESS THAN ('20200909'),
PARTITION PT_20200909 VALUES LESS THAN ('20200910'),
PARTITION PT_20200910 VALUES LESS THAN ('20200911'),
PARTITION PT_99999999 VALUES LESS THAN (MAXVALUE)
);
CREATE or REPLACE FUNCTION
BEGIN
RETURN ARG;
END;
/
set lines 200
EXPLAIN PLAN FOR SELECT * FROM
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------
Plan hash value: 1909639130
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 60 | 2 (0)| 00:00:01 | | |
| 1 | PARTITION RANGE ALL| | 1 | 60 | 2 (0)| 00:00:01 | 1 | 11 |
|* 2 | TABLE ACCESS FULL |
-----------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("COL4"<="
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
18 rows selected.
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------
Plan hash value: 1276201164
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 60 | 2 (0)| 00:00:01 | | |
| 1 | PARTITION RANGE ITERATOR| | 1 | 60 | 2 (0)| 00:00:01 | KEY | KEY |
|* 2 | TABLE ACCESS FULL |
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("COL4"<="
Note
-----
- dynamic sampling used for this statement (level=2)
18 rows selected.
Upgrade to 19c.
This is a behavior change introduced by the fix of unpublished Bug 27175987, which is included in 19c.
The fix of unpublished Bug 27175987 is to disable partition pruning for predicates that involve non-deterministic PL/SQL functions.
This eventually should be solved with the following internal bug:
Bug 35601787 - BULK DELETE ON LIST-HASH COMPOSITE PARITITIONED TABLE GIVES WRONG RESULT
Please also reference the following:
Document 35601787.8 - Bug 35601787 - Wrong results from partition pruning when predicate has PL/SQL functions and removal of Bug 27175987 restriction
The permanent solution is to apply patch 35601787.
The following is a possible workaround to enable partition pruning:
SQL> CREATE or REPLACE FUNCTION
BEGIN
RETURN ARG;
END;
/
2 3 4 5
Function created.
SQL> EXPLAIN PLAN FOR SELECT * FROM
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
Explained.
SQL>
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1276201164
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 60 | 2 (0)| 00:00:01 | | |
| 1 | PARTITION RANGE ITERATOR| | 1 | 60 | 2 (0)| 00:00:01 | KEY | KEY |
|* 2 | TABLE ACCESS FULL |
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("COL4"<="
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
18 rows selected.
SQL>
关键字DETERMINISTIC声明了:函数在给定相同的输入时,总会返回完全相同的输出。如果我们要用一个用户自定义函数来创建索引,那么这个关键字是必不可少的。通过这个关键字,Oracle就可以相信这个函数:只要提供相同的输入,不论这个函数调用多少次,它一定会返回相同的值。如果不是这样,通过索引访问数据时,可能会得到与全表扫描不同的答案。
多次看到DETERMINISTIC,一直很疑惑,今天做了一个实验。我们欺骗ORACLE说是一个DETERMINISTIC函数,它在SQL中只调用一次。如果不使用DETERMINISTIC,可以看到出来的值都不一样。使用DETERMINISTIC后,不同的会话都出来一样的值。
SQL> create or replace function f_t(i_p int) return number DETERMINISTIC is
i_rtn number;
begin
i_rtn := i_p * dbms_random.value(1,10);
return i_rtn;
end;
/
函数已创建。
session1:
SQL> select LEVEL,f_t(1) FROM DUAL CONNECT BY LEVEL<=10;
LEVEL F_T(1)
---------- ----------
1 2.55732959
2 2.55732959
3 2.55732959
4 2.55732959
5 2.55732959
6 2.55732959
7 2.55732959
8 2.55732959
9 2.55732959
10 2.55732959
已选择10行。
session2:
SQL> select LEVEL,f_t(1) FROM DUAL CONNECT BY LEVEL<=10;
LEVEL F_T(1)
---------- ----------
1 2.55732959
2 2.55732959
3 2.55732959
4 2.55732959
5 2.55732959
6 2.55732959
7 2.55732959
8 2.55732959
9 2.55732959
10 2.55732959
已选择10行。
SQL> create or replace function f_t(i_p int) return number is
i_rtn number;
begin
i_rtn := i_p * dbms_random.value(1,10);
return i_rtn;
end;
/
函数已创建。
SQL> select LEVEL,f_t(1) FROM DUAL CONNECT BY LEVEL<=10;
LEVEL F_T(1)
---------- ----------
1 8.48649118
2 8.9396978
3 2.2786135
4 5.29205905
5 5.32847713
6 8.70095819
7 6.20471031
8 2.00101537
9 3.53814265
10 3.64991086
已选择10行。
This note gives a brief overview of bug 35246239.
The content was last updated on: 26-AUG-2023
Click here for details of each of the sections below.
Product (Component) Oracle Server (Rdbms) Range of versions believed to be affected Versions BELOW 23.1 Versions confirmed as being affected
- (None Specified)
Platforms affected Generic (all / most platforms affected)
Note that this fix can cause / expose the problem described in Bug:35601787
Note that this fix has been superseded by the fix in Bug:35601787
This fix has been superseded - please see the fixed version information for Bug:35601787 . The box below only shows versions where the code change/s for 35246239 are first included - those versions may not contain the later improved fix.
The fix for 35246239 is first included in
- (None Specified)
Symptoms: |
Related To: |
|
|
Partition pruning is disabled for filter predicates on partition key column that involve non-deterministic PL/SQL functions. This restriction was introduced by the fix in Bug 27175987. Rediscovery information If you do not get partition pruning for predicates on the partition key that involve PL/SQL functions that have not been marked as deterministic, then you may have hit this bug. Workaround None.