Oracle 如何制作确定性函数?
我正在尝试根据一个函数的结果创建一个索引,该函数应用于一个列,在该列中我必须提取一个数字Oracle 如何制作确定性函数?,oracle,oracle10g,indexing,deterministic,Oracle,Oracle10g,Indexing,Deterministic,我正在尝试根据一个函数的结果创建一个索引,该函数应用于一个列,在该列中我必须提取一个数字 Example String: ...someText...&idDocunet=799493...someText... [799493] <- Note the number The function: replace(regexp_substr(parametros, '&idDocunet=\d+'), 'idD
Example String: ...someText...&idDocunet=799493...someText...
[799493] <- Note the number
The function: replace(regexp_substr(parametros, '&idDocunet=\d+'), 'idDocunet=', NULL)
The index: create index example on MY_TABLE (replace(regexp_substr(parametros, '&idDocunet=\d+'), 'idDocunet=', NULL));
还是这个
SELECT *
FROM my_table
WHERE replace(regexp_substr(parametros, '&idDocunet=\d+'), 'idDocunet=', NULL) = 799493
或者加入
不使用索引,它每次都执行完整表扫描。我相信索引是确定性的,因为它总是返回数字,或者null,但我不知道表达式是否太复杂,无法使用。我还尝试将代码移动到函数中,但结果是一样的。我相信关键在于这个确定性的东西(我做错了吗?)和/或原始列上有空值的表。如何确保使用索引?这就是功能:
create or replace function extraer_doc_id(viParam VARCHAR2) return varchar2 is
begin
RETURN replace(regexp_substr(viParam, '&idDocunet=\d+'), 'idDocunet=', NULL);
end extraer_doc_id;
我也执行了这个
ANALYZE TABLE my_table COMPUTE STATISTICS;
但这似乎无关紧要。要创建确定性函数,请在返回类型声明旁边使用
deterministic
子句,
请参阅语法
您创建了一个基于函数的索引,该索引引用了my_列字段:replace(regexp_substr(**my_column**, '&idDocunet=\d+'), 'idDocunet=', NULL)
但是在查询的where
子句中,您使用的函数与索引中的函数不同(不同列):
因此Oracle无法将此索引用于此查询,因为这些表达式不同。
也不要使用
ANALYZE TABLE
,此命令在10g中已被弃用,请改用:要创建确定性函数,请在返回类型声明旁边使用deterministic
子句,
请参阅语法
您创建了一个基于函数的索引,该索引引用了my_列字段:replace(regexp_substr(**my_column**, '&idDocunet=\d+'), 'idDocunet=', NULL)
但是在查询的where
子句中,您使用的函数与索引中的函数不同(不同列):
因此Oracle无法将此索引用于此查询,因为这些表达式不同。
也不要使用
ANALYZE TABLE
,此命令在10g中已被弃用,请改用:要使用基于函数的索引,您应该:
- 在自己的函数中使用
子句李>DETERMINISTIC
- 查询必须使用与您提到的创建索引相同的函数和列
set define off
drop table test;
create table test ( s varchar2( 100 ) )
/
create or replace function getDocId( p varchar2 )
return number
deterministic
is
begin
return to_number( regexp_replace(p, '^.*&idDocunet=(\d+).*$', '\1') );
end getDocId;
/
create index test_fbi on test( getDocId( s ) )
/
insert into test values( '...someText...&idDocunet=799493...someText...' )
/
现在让我们制定一个计划:
explain plan for
select *
from test
where getdocid( s ) = 1
/
select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
Plan hash value: 3113607502
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 65 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 65 | 1 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TEST_FBI | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("TEST"."GETDOCID"("S")=1)
Note
-----
- dynamic sampling used for this statement (level=2)
18 rows selected
如您所见,使用了索引。要使用基于函数的索引,您应该:
- 在自己的函数中使用
子句李>DETERMINISTIC
- 查询必须使用与您提到的创建索引相同的函数和列
set define off
drop table test;
create table test ( s varchar2( 100 ) )
/
create or replace function getDocId( p varchar2 )
return number
deterministic
is
begin
return to_number( regexp_replace(p, '^.*&idDocunet=(\d+).*$', '\1') );
end getDocId;
/
create index test_fbi on test( getDocId( s ) )
/
insert into test values( '...someText...&idDocunet=799493...someText...' )
/
现在让我们制定一个计划:
explain plan for
select *
from test
where getdocid( s ) = 1
/
select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
Plan hash value: 3113607502
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 65 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 65 | 1 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TEST_FBI | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("TEST"."GETDOCID"("S")=1)
Note
-----
- dynamic sampling used for this statement (level=2)
18 rows selected
正如您所看到的,使用了索引。Hi,对于“parametros”这件事,当我在这里用“my_column”编写示例时,我忘记了更新它,我确实使用了相同的函数进行了测试,但没有使用索引。我将在我的函数中使用deterministic子句来测试它,但它应该与查询一起工作,对吗?嗨,对于“parametros”这件事,我只是忘记了更新示例,当我在这里用“my_column”编写它时,我确实使用了相同的函数进行了测试,但没有使用索引。我将在我的函数中使用deterministic子句测试它,但它应该与查询一起工作,对吗?