Function-based index, NOT NULL bug?
ALTER SESSION SET OPTIMIZER_MODE = FIRST_ROWS_10;
ALTER SESSION SET QUERY_REWRITE_ENABLED = TRUE;
CREATE TABLE xxx (code CHAR(6) NOT NULL);
create index xxx_idx on xxx (upper(code));
select * from xxx order by upper(code);
-> ORA-03113: end-of-file on communication channel
(Oracle 9.0.1, Windows 2000)
I know it's quite a long-time that anyone replied this post, but I just need to report our attempts to workaround that.
Dropping function-based indexes in primary database, just before creation of Logical Dataguard hasn't solved our problem, neither dropping indexes in logical database.
In my opinion and after some docs in metalink, I think there's no way to solve it.
Or you drop them or you migrate to 10g.
Regards.
Similar Messages
-
Query not considering function based index in oracle 11g
I have a query which used Function Based Index when run in oracle 9i but when I run the same query
without any changes, it does not consider index. Below is the query:
SELECT distinct patient_role.domain_key, patient_role.patient_role_key,
patient_role.emergency_contact_name,
patient_role.emergency_contact_phone, patient_role.emergency_contact_note,
patient_role.emergency_contact_relation_id,
patient_role.financial_class_desc_id, no_known_allergies, patient_role.CREATED_BY,
patient_role.CREATED_TIMESTAMP,
patient_role.CREATED_TIMESTAMP_TZ, patient_role.UPDATED_BY, patient_role.UPDATED_TIMESTAMP,
patient_role.UPDATED_TIMESTAMP_TZ,
patient_role.discontinued_date
FROM encounter, patient_role
WHERE patient_role.patient_role_key = encounter.patient_role_key
AND UPPER(TRIM(leading :SYS_B_0 from encounter.account_number)) = UPPER(TRIM(leading :SYS_B_1 from
:SYS_B_2))
AND patient_role.discontinued_date IS null
AND encounter.discontinued_date IS null ;
Index definition:
CREATE INDEX "user1"."IX_TRIM_ACCOUNT_NUMBER" ON "user1."ENCOUNTER" (UPPER(TRIM(LEADING
'0' FROM "ACCOUNT_NUMBER")), "PATIENT_ROLE_KEY", "DOMAIN_KEY", "DISCONTINUED_DATE")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT)
TABLESPACE "user1"
Database : Oracle 11g (11.2.0.3)
O/S : Linux 64 bit (the query does not consider index even on windows os)
Any suggestions?
-Onkar
Edited by: onkar.nath on Jul 2, 2012 3:32 PMOnkar,
I don't appreciate you posting this question in several forums at the same time.
If I would know you also posted this on Asktom, I wouldn't even have bothered.
As to your 'issue':
First of all: somehow cursor_sharing MUST have been set to FORCE. Oracle is a predictable system, not a fruitmachine.
Your statement the '0' is replaced by a bind variable anyway is simply false. If you really believe it is not false, SUBMIT a SR.
But your real issue is not Oracle: it is your 'application', which is a mess anyway. Allowing for alphanumeric numbers is a really bad idea.
Right now you are already putting workaround on workaround on workaround on workaround.
Issue is the application: it is terminal., and you either need to kill it, or to replace it.
Sybrand Bakker
Senior Oracle DBA -
Err ORA-00439 feature not enabled: function-based indexes
How can I enable function based indexes?
Database Version is 8i Release 8.1.6.0.0.
I've done the following steps:
The init-parameter compatible is set to 8.1.0.0.0.
I've altered the session parameters
QUERY_REWRITE_INTEGRITY to TRUSTED and
QUERY_REWRITE_ENABLED to TRUE.
But it still doesn't work.
I would appreciate your help.
MartinFunction Based Index feature is not available in the Standard Edition of Oracle. This feature is available ONLY in the Enterprise and Personal Editions.
Use the V$OPTION view to see the list of installed options.
If the option is installed, you will see for "Function-based indexes":
PARAMETER VALUE
Function-based indexes TRUE
null -
Function based indexing v8.1.7 not working
I have created a function based index on a column and when I run my query although I get the correct results I seem to be doing a full table scan instead of using the index.
Are there any known bugs or additional parameter setting for function based indexing in 8i ?
Thanks
Bob IRobert
To use Functional Index you to set following parameters in INIT.ORA, Compatiable should be more than 8.1.0
query_rewrite_enabled = TRUE
query_rewrite_integrity = TRUSTED
Compatiable = 8.1.7.0
optimizer = Choose
Create index indexname on table (lower(column));
then analyze table
Analyze table tablename compute statistics;
Regards
Shailesh
null -
Why Segment shrink is not supported for tables with function-based indexes
As we all know , Segment shrink is not supported for tables with function-based indexes.
But i'm very confused .
Why Segment shrink is not supported for tables with function-based indexes ?? what's its essential?Creating a function based index creates a hidden virtual column (you'll see it if you query user_tab_cols) and once you index a virtual column you can no longer shrink the table:orcl> create table t1(c1 number,c2 as (c1 * 2)) segment creation immediate;
Table created.
orcl> alter table t1 enable row movement;
Table altered.
orcl>
orcl> alter table t1 shrink space;
Table altered.
orcl> create index i2 on t1(c2);
Index created.
orcl> alter table t1 shrink space;
alter table t1 shrink space
ERROR at line 1:
ORA-10631: SHRINK clause should not be specified for this object
orcl>so the issue is not with function based indexes per se, it is a level beneath that. Perhaps because the virtual column has no physical existance, when the row is moved there is no reason for Oracle to realize that an index needs updating? I haven't attempted to reverse engineer this, I would be interested to know if anyone else has. -
Impdp not importing function based index correctly.
We noticed that a process running in our develop database was running much faster than in the production database. After investigating we found that on the development database the process was using an index on the main large table and on the production database the index was ignored and full table scans of the large table were being used.
The data in the tables was the same, statistics were up-to-date, etc. Looking closer we saw that the index on the production database was function based because it had the DESC keyword on one column in the index. On the development database all columns of the index were ASC and thus it was a "normal" index. This was very confusing since we had just refreshed the development database from production using expdp/impdp. I ran impdp with the sqlfiles option to capture the DDL from the export file for the index in question from the production database:
CREATE UNIQUE INDEX "SYSADM"."PS_SF_1098_ITEM" ON "SYSADM"."PS_SF_1098_ITEM" ("EMPLID", "SF_TIN", "CALENDAR_YEAR", "SEQ_NO" DESC, "DTL_SEQ_NBR")
PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 40960 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "PSINDEX" ;
I then dropped the table/index in the development database and reimported just this one table. Sure enough, the index wasn't created as a function based index (no DESC keyword on SEQ_NO column):
CREATE UNIQUE INDEX "SYSADM"."PS_SF_1098_ITEM" ON "SYSADM"."PS_SF_1098_ITEM" ("EMPLID", "SF_TIN", "CALENDAR_YEAR", "SEQ_NO", "DTL_SEQ_NBR")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 40960 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "PSINDEX" ;
I've researched this extensively and can't find any information on why this is happening. Any ideas before I open a SR?
BTW.... version is 11.1.0.7 patchset 31 on Windows Server 2003. Both dev and prod environments are identical.
Thanks,
DanWorking on something else I noticed the following two "hidden" init.ora parameters in both my dev and production databases:
*._disable_function_based_index=TRUE
*._ignore_desc_in_index=TRUE
The first parameter explains why the index (function based) was being ignored in my production database. The second explains why the index is created without the DESC keyword in my dev database from an export from my prod database. I guess you do learn something new every day :)
These databases are used by Peoplesoft applications and I found several posts saying that function based indexes created by Peoplesoft were causing performance and/or data validity problems and users were instructed to set the above parameters so the FIB's weren't used. So, everything is working as expected/designed. I will contact Peoplesoft Tech Support to see if users are still encouraged to set the above parameters.
Dan -
Dilemma regarding function based indexes
Hello,
I have a dilemma regarding function based indexes.
I have read Note:66277.1 on the Metalink discussing thoroughly the subject of “Concepts and Usage of Function Based Indexes”.
This doc was revised on 30-May-2006 so I was sure it referred to 9i and 10g.
This doc as well as other docs on the web claim that in order to use FBI (function based indexes) one must set the following parameters (can be done also at session level)
QUERY_REWRITE_ENABLED = TRUE
QUERY_REWRITE_INTEGRITY = TRUSTED
Also the schema that is owner of the FBI should be granted with QUERY REWRITE sys priv and statistics should be collected since FBI is usable only by CBO (cost based optimizer).
I have tested it and it works, my problem was that it worked
(1) Without granting the QUERY REWRITE to the owning schema.
(2) QUERY_REWRITE_ENABLED was set to false.
(3) QUERY_REWRITE_INTEGRITY was set to enforced.
I have conducted my tests on 9.2.0.6 and found no evidence in the docs (10g) saying the above is required or not.
I found at http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:1197786003246 the following:
“Oracle9iR2 relaxed this so that the FBI on the builtin function may be used.”
so I have tested it with my own function:
create or replace function upper2( p_str in varchar2 ) return
varchar2 DETERMINISTIC
as
begin
return upper(p_str);
end;
=>
Also (yes you guessed right), without any privilege granted nor parameter setting the optimizer picked my FBI.
Can anyone refer me to a place documenting this behavior as a correct one?
Other comments?
Regards,
Tal Olier ([email protected])Got an answer from Oracle support:
19-DEC-06 18:04:31 GMT
(Update for record id(s): 101017780,101017796)
QUESTION
========
Questions about the options required in 10g related to Function Based Indexes, and the correct
behaviors associated with them.
ANSWER
======
For 10g:
These requirements are no longer true in 10g. This has already clarified by
development in the Bug 3999326 which is available on metalink.
For 9I:
For the creation of a function-based index in your own schema, you must be
granted the QUERY REWRITE system privileges. To create the index in another
schema or on another schema's tables, you must have the CREATE ANY INDEX
and GLOBAL QUERY REWRITE privileges.
You must have the following initialization parameters defined to create a
function-based index:
QUERY_REWRITE_INTEGRITY set to TRUSTED
QUERY_REWRITE_ENABLED set to TRUE
COMPATIBLE set to 8.1.0.0.0 or a greater value
Additionally, to use a function-based index:
The table must be analyzed after the index is created.
The query must be guaranteed not to need any NULL values from the indexed
expression, since NULL values are not stored in indexes.
However, in 9.2.0.4 patchset, these prerequisites do not apply and one can
create function-based indexes without any of the above to be true. This is not
the case in 9.2.0.3, not in 8.1.7.
Reference: Oracle 9i R2 Administrators Guide
So as mentioned above that is why you didnt have any errors
Please back to us if any further information is need, and we will be pleased to
assist you further.
Thank You,
Best Regards,
Mina Anes -
Function Based Index And Selectivity
Hi All,
I have some doubts w.r.t FBI.I am on 10gR2 (10.2.0.4) with Solaris 5.9
I was under impression that FBI does not provide guaranteed index access and CBO choose access pattern purely on basis of available stats and query selectivity.
However, many a times i found that CBO is going for FBI even in case when FTS provides better query elapsed time.
I created following test case:
create table fbi_test (id number,flag varchar2(1));
begin
for i in 1..1000000
loop
insert into fbi_test values(i,'Y');
end loop;
end;
commit;
begin
for i in 1..10
loop
insert into fbi_test values(i,'N');
end loop;
end;
commit;
ANALYZE TABLE FBI_TEST COMPUTE STATISTICS;
CREATE INDEX fbi_test_FBI
ON fbi_test (CASE WHEN flag = 'Y' THEN 1 ELSE NULL END);
Autotrace for FBI ACCESS
SQL> select *from fbi_test where (CASE WHEN flag = 'Y' THEN 1 ELSE NULL END)=1;
1000000 rows selected.
Elapsed: 00:00:18.43
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 10000 | 50000 | 342 (1)|
| 1 | TABLE ACCESS BY INDEX ROWID| FBI_TEST | 10000 | 50000 | 342 (1)|
|* 2 | INDEX RANGE SCAN | FBI_TEST_FBI | 4000 | | 1958 (1)|
Statistics
0 recursive calls
0 db block gets
136812 consistent gets
0 physical reads
0 redo size
22180292 bytes sent via SQL*Net to client
733814 bytes received via SQL*Net from client
66668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1000000 rows processed
Autotrace for FTS
SQL> select *from fbi_test where flag = 'Y';
1000000 rows selected.
Elapsed: 00:00:16.56
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 500K| 2441K| 371 (9)|
|* 1 | TABLE ACCESS FULL| FBI_TEST | 500K| 2441K| 371 (9)|
Statistics
0 recursive calls
0 db block gets
68372 consistent gets
0 physical reads
0 redo size
22180292 bytes sent via SQL*Net to client
733814 bytes received via SQL*Net from client
66668 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1000000 rows processed
FYI...
SQL> show parameter opt
NAME TYPE VALUE
filesystemio_options string asynch
object_cache_optimal_size integer 102400
optimizer_dynamic_sampling integer 2
optimizer_features_enable string 10.2.0.3
optimizer_index_caching integer 0
optimizer_index_cost_adj integer 100
optimizer_mode string ALL_ROWS
optimizer_secure_view_merging boolean TRUE
plsql_optimize_level integer 2
My questions are,
1.why oracle optimizer is going for FBI with high cardinality of 100000 rows?
2.Why cost of FTS is high (371) as compare to FBI (342) eventhough FTS is having fewer IO (68372) + Less Elapsed Time?
3.Why Optimizer is considering ELAPSED TIME during plan generation?
Any inpute would be highly appreciated.user635930 wrote:
Hi All,
I have some doubts w.r.t FBI.I am on 10gR2 (10.2.0.4) with Solaris 5.9
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
| 0 | SELECT STATEMENT | | 10000 | 50000 | 342 (1)|
| 1 | TABLE ACCESS BY INDEX ROWID| FBI_TEST | 10000 | 50000 | 342 (1)|
|* 2 | INDEX RANGE SCAN | FBI_TEST_FBI | 4000 | | 1958 (1)|
---------------------------------------------------------------------------------You're seeing three different effects here.
First - for the table access by index, Oracle has "lost" the cost of the index range scan - notice that the total cost of the query is 342, but the cost of the index access is 1958. The total cost of the query should be 2,300 and Oracle should have chosen the full tablescan automatically.
Second, the stats on the index show just one distinct value for "distinct_keys", and the optimizer has decided (for no reason I can think of - it may be a bug) to assume a 0.4% selectivity on the index.
Third, the estimated cardinality of the table and index lines differs. Whatever Oracle has done in the index line has been forgotten, and the cardinality of the table line has been based on the predicate given by your case statement and, as a "complex function", that predicate has been given a selectivity of 1% - hence the 10,000 rows estimate.
The combination of unsuitable statistics, an extreme case, and a couple of quirks in the optimizer mean that the chosen path is clearly unsuitable.
[Addendum]: It just occurred to me that part of the problem is that you collected stats on the table before you created the index. Given you're running 10g, the 'create index' would automatically generate index stats at the same time - but since it's a function-based index, there's a "virtual column" created for the table as well, and that column won't have any statistics on it - which is why you get the "fixed percentage" selectivities.
Regards
Jonathan Lewis
http://jonathanlewis.wordpress.com
http://www.jlcomp.demon.co.uk
"Science is more than a body of knowledge; it is a way of thinking" Carl Sagan
Edited by: Jonathan Lewis on Nov 29, 2008 1:15 PM -
Function-based index with OR in the wher-clause
We have some problems with functin-based indexes and
the or-condition in a where-clause.
--We use Oracle 8i (8.1.7)
create table TPERSON(ID number(10),NAME varchar2(20),...);
create index I_NORMAL_TPERSON_NAME on TPERSON(NAME);
create index I_FUNCTION_TPERSON_NAME on TPERSON(UPPER(NAME));
The following two statements run very fast on a large table
and the execution-plan asure the usage of the indexes
(-while the session is appropriate configured and the table is analyzed):
1) select count(ID) FROM TPERSON where upper(NAME) like 'MIL%';
2) select count(ID) from TPERSON where NAME like 'Mil%' or (3=5);
In particular we see that a normal index is used while the where-clause contains
an OR-CONDITION.
But if we try the similarly select-statement
3) select count(ID) FROM TPERSON where upper(NAME) like 'MIL%' or (3=5);
the CBO will not use the function-index I_FUNCTION_TPERSON_NAME and we have a full table scan in the execution-plan.
(This behavior we only expect with views but not with indexes.)
We ask for an advice like a hint, which enable the CBO-usage
of function-based indexes in connection with OR.
This problem seems to be artificial because it contains this dummy logic:
or (3=5).
This steams from an prepared statement, where this kind of boolean
flag reduce the amount of different select-statements needed for
covering the hole business-logic, while using bind-variables for the
concrete query-parameters.
A more realistic (still boild down) version of our select-statement is:
select * FROM TPERSON
where (upper(NAME) like 'MIL%' or (NAME is null))
and (upper(FIRSTNAME) like 'MICH% or (FIRSTNAME is null))
and ...;
thank you for time..
email: [email protected]In the realistic statement you write :
select * FROM TPERSON
where (upper(NAME) like 'MIL%' or (NAME is null))
and (upper(FIRSTNAME) like 'MICH% or (FIRSTNAME is null))
and ...;
as far as i know, NULL values are not indexed, "or (NAME is NULL)" have to generate a full table scan.
HTH
We have some problems with functin-based indexes and
the or-condition in a where-clause.
--We use Oracle 8i (8.1.7)
create table TPERSON(ID number(10),NAME varchar2(20),...);
create index I_NORMAL_TPERSON_NAME on TPERSON(NAME);
create index I_FUNCTION_TPERSON_NAME on TPERSON(UPPER(NAME));
The following two statements run very fast on a large table
and the execution-plan asure the usage of the indexes
(-while the session is appropriate configured and the table is analyzed):
1) select count(ID) FROM TPERSON where upper(NAME) like 'MIL%';
2) select count(ID) from TPERSON where NAME like 'Mil%' or (3=5);
In particular we see that a normal index is used while the where-clause contains
an OR-CONDITION.
But if we try the similarly select-statement
3) select count(ID) FROM TPERSON where upper(NAME) like 'MIL%' or (3=5);
the CBO will not use the function-index I_FUNCTION_TPERSON_NAME and we have a full table scan in the execution-plan.
(This behavior we only expect with views but not with indexes.)
We ask for an advice like a hint, which enable the CBO-usage
of function-based indexes in connection with OR.
This problem seems to be artificial because it contains this dummy logic:
or (3=5).
This steams from an prepared statement, where this kind of boolean
flag reduce the amount of different select-statements needed for
covering the hole business-logic, while using bind-variables for the
concrete query-parameters.
A more realistic (still boild down) version of our select-statement is:
select * FROM TPERSON
where (upper(NAME) like 'MIL%' or (NAME is null))
and (upper(FIRSTNAME) like 'MICH% or (FIRSTNAME is null))
and ...;
thank you for time..
email: [email protected] -
Creation of function based index using escape
Hello,
I have the following SQL, sometimes performing bad:
SELECT DISTINCT UPPER(A.PROCESSIDCODE), UPPER(A.RULENAME), CHARSET
FROM XIB_DETECT A, XIB_PROCESSIDPROPERTIES B, XIB_RULES C
WHERE ( A.KEY1 = :P1 OR ( :P1 like REPLACE(REPLACE(REPLACE(REPLACE(KEY1,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\' AND A.REGFLAGS1 = 'Y') OR A.KEY1 = '*' AND A.REGFLAGS1 = 'Y')
AND (A.KEY2 = :P2 OR ( :P2 like REPLACE(REPLACE(REPLACE(REPLACE(KEY2,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\' AND A.REGFLAGS2 = 'Y') OR (A.KEY2 IS NULL AND A.REGFLAGS2 IS NULL ) )
AND (A.KEY3 = :P3 OR ( :P3 like REPLACE(REPLACE(REPLACE(REPLACE(KEY3,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\' AND A.REGFLAGS3 = 'Y') OR (A.KEY3 IS NULL AND A.REGFLAGS3 IS NULL ) )
AND (A.KEY4 = :P4 OR ( :P4 like REPLACE(REPLACE(REPLACE(REPLACE(KEY4,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\' AND A.REGFLAGS4 = 'Y') OR (A.KEY4 IS NULL AND A.REGFLAGS4 IS NULL ) )
AND (A.KEY5 = :P5 OR ( :P5 like REPLACE(REPLACE(REPLACE(REPLACE(KEY5,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\' AND A.REGFLAGS5 = 'Y') OR (A.KEY5 IS NULL AND A.REGFLAGS5 IS NULL ) )
AND (A.KEY6 IS NULL OR A.KEY6 = '*' AND REGFLAGS6 = 'Y')
AND (A.KEY7 IS NULL OR A.KEY7 = '*' AND REGFLAGS7 = 'Y')
AND (A.KEY8 IS NULL OR A.KEY8 = '*' AND REGFLAGS8 = 'Y')
AND (A.KEY9 IS NULL OR A.KEY9 = '*' AND REGFLAGS9 = 'Y')
AND (A.KEY10 IS NULL OR A.KEY10 = '*' AND REGFLAGS10 = 'Y')
AND ( ( A.PROCESSIDCODE IS NOT NULL AND UPPER(A.PROCESSIDCODE) = UPPER(B.PROCESSIDCODE) AND A.XLEVEL = B.XLEVEL AND B.ACTIVEFLAG = 'Y' )
OR ( A.RULENAME IS NOT NULL AND UPPER(A.RULENAME) = UPPER(C.RULENAME) AND A.XLEVEL = C.XLEVEL AND C.ACTIVEFLAG = 'Y' ) );
Now I want to create a function based index on the key1 column:
CREATE INDEX xib_detect_ix ON xib_detect (REPLACE(REPLACE(REPLACE(REPLACE(KEY1,'%', '\%'),'_', '\_'),'?', '_'),'*','%') escape '\') TABLESPACE ... ONLINE;
However, this is not working with "escape" '\', throwing: ORA-00907: missing right parenthesis
Any idea how to create an index on this construct with "escape"?
Database version is 10.2.0.3.
Thanks a lot.
Regards
OliverHi,
You can get the "missing right parenthesis" error for many different syntax errors.
In this case, you really are missing a right parenthesis. Your statement has 5 left '('s, but only 4 right ')'s. It's easy to see this if you format your code:
CREATE INDEX xib_detect_ix
ON xib_detect ( REPLACE ( REPLACE ( REPLACE ( REPLACE ( KEY1
escape '\'
ESCAPE is an option that you can use with the LIKE operator. It gives you a mechanism for cancelling the special meaning of symbols like '%'. You're not using the LIKE operator to create the index. You're only using REPLACE, and no characters have any special meaning in REPLACE, so there's no way (or reason) to escape them. Use ESCAPE in queries that use LIKE, when appropriate. -
Function Based Index on Date Column
Hi All,
I need to execute a query like this :
SELECT * FROM ORDERS WHERE APPROVE_DATE IS NULL
I read anywhere that this will cause unnecessary FTS so that I should create function based index.
I have tried one below , but not sure that this is correct approach :
CREATE INDEX idx_1
ON ORDERS (NVL(APPROVE_DATE, '01-JAN-1900'));
SELECT * FROM ORDERS WHERE NVL(APPROVE_DATE, '01-JAN-1900') = '01-JAN-1900'
Is this a correct approach ?
Thank you,
xtantoA SQL_TRACE output will explain clearly what Justin has stated.
I have created a table T based on all_objects.
SQL> desc t
Name Null? Type
OWNER NOT NULL VARCHAR2(30)
OBJECT_NAME NOT NULL VARCHAR2(30)
SUBOBJECT_NAME VARCHAR2(30)
OBJECT_ID NOT NULL NUMBER
DATA_OBJECT_ID NUMBER
OBJECT_TYPE VARCHAR2(19)
CREATED DATE
LAST_DDL_TIME NOT NULL DATE
TIMESTAMP VARCHAR2(19)
STATUS VARCHAR2(7)
TEMPORARY VARCHAR2(1)
GENERATED VARCHAR2(1)
SECONDARY VARCHAR2(1)
CASE I_
SQL> select count(1) from t
2 /
COUNT(1)
934320
SQL> select count(1) from t where created is null
2 /
COUNT(1)
2376The number of null values in CREATED column is proportionately very small.
Now i execute the query without function based index.
select *
from t
where created is null
call count cpu elapsed disk query current rows
Parse 1 0.00 0.09 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 160 0.04 0.10 0 12662 0 2376
total 162 0.04 0.19 0 12662 0 2376
Rows Execution Plan
0 SELECT STATEMENT GOAL: ALL_ROWS
2376 TABLE ACCESS GOAL: ANALYZED (FULL) OF 'T' (TABLE)And here is the query that uses the function based index
select *
from t
where nvl(created,to_date('01-01-1900','DD-MM-YYYY')) = to_date('01-01-1900','DD-MM-YYYY')
call count cpu elapsed disk query current rows
Parse 1 0.01 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 160 0.01 0.01 0 698 0 2376
total 162 0.03 0.01 0 698 0 2376
Rows Execution Plan
0 SELECT STATEMENT GOAL: ALL_ROWS
2376 TABLE ACCESS GOAL: ANALYZED (BY INDEX ROWID) OF 'T' (TABLE)
2376 INDEX GOAL: ANALYZED (RANGE SCAN) OF 'T_FN_IDX' (INDEX)Its very obvious from the above output that the Function Based Index as increased the performance.
CASE II_
SQL> select count(1) from t
2 /
COUNT(1)
934320
SQL> select count(1) from t where created is null
2 /
COUNT(1)
202168Now the null values in the CREATED column is proportionately large than the first test case.
Now lets see without using the function based index
select *
from t
where created is null
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 13479 0.46 0.71 2 25832 0 202168
total 13481 0.46 0.71 2 25832 0 202168
Rows Execution Plan
0 SELECT STATEMENT GOAL: ALL_ROWS
202168 TABLE ACCESS GOAL: ANALYZED (FULL) OF 'T' (TABLE)Now iam trying to use the function based index
select *
from t
where nvl(created,to_date('01-01-1900','DD-MM-YYYY')) = to_date('01-01-1900','DD-MM-YYYY')
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 13479 0.54 0.84 0 33826 0 202168
total 13481 0.54 0.84 0 33826 0 202168
Rows Execution Plan
0 SELECT STATEMENT GOAL: ALL_ROWS
202168 TABLE ACCESS GOAL: ANALYZED (FULL) OF 'T' (TABLE)Its obvious from the result that oracle has decided to go for a FULL TABLE SCAN even when an index was available.
So just having a function based index is not going to increase the query performance. There are lot of other factors to be considered as stated above.
Thanks,
Karthick. -
Hi All,
select * from v$version;
BANNER
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
PL/SQL Release 11.1.0.7.0 - Production
CORE 11.1.0.7.0 Production
TNS for Linux: Version 11.1.0.7.0 - Production
NLSRTL Version 11.1.0.7.0 - ProductionI have a 10GB partitioned table which has INVOICE_DUE_DATE column. Table is partitioned on CREATION_DATE. All records which has CREATION_DATE less than 01-jan-2010 have INVOICE_DUE_DATE set to NULL and new records (for year 2011)are updated with recent date(i.e. sysdate) by 'due_date_update' process. Some developers want indexing on INVOICE_DUE_DATE column as they have SLA critical reports running against INVOICE_DUE_DATE column. (where INVOICE_DUE_DATE > :B1) B1 could be any date in 2011.
As of now, ~85% records are having INVOICE_DUE_DATE set to NULL.
Given above scenarios,Can i use function based index to index all rows where INVOICE_DUE_DATE is any date in 2011 ?
Edited by: OraDBA02 on Jan 11, 2011 4:00 AMOraDBA02 wrote:
Given above scenarios,Can i use function based index to index all rows where INVOICE_DUE_DATE is any date in 2011 ?I suppose you could, but you might not need to. If you had an index that just contained the INVOICE_DUE_DATE column it wouldn't index the NULL values anyways. -
Oracle 8i Function-based index
Hi,
i have problem with making Oracle8i to use function-based index. I am using version 8.1.6 Enterprise Edition.
So here is the test I did
CREATE INDEX first_name_index ON customer ( UPPER(first_name)) ;
alter session set QUERY_REWRITE_ENABLED = TRUE;
alter session set QUERY_REWRITE_INTEGRITY=TRUSTED;
ANALYZE TABLE customer COMPUTE STATISTICS;
alter index first_name_index compute statistics;
Everything seemed to be as required by Oracle but it doesn't use this function-based index when I make
select *
from customer
where upper(first_name) like 'J%';
I test it on large table and with table with few hundred rows. I don't have NULLs in that field.
Can anyone help me with this.I would not create an index to have it prepared for an ORDER BY. An index is quite costly in DML opperations and space as well. More, a function based index will be costlier as the function has to be called for every read and/or write.
Do not forget that indexes a created for a direct access to data and not for sorting purposes.
George -
Query Transformation in Function Based Index's Expression
Hi All,
I am having a wired issue with Function Based Indexes on Orcale 10.2.0.3 running on Solaris 5.9.
I have created two FBI on two tables using following syntax.
CREATE INDEX EQHUB.IDX_BBO_WRT_DES_FBI ON EQHUB.BBO_WARRANT_PRICING (CASE WHEN latest_version_flag = 'Y' THEN 1 ELSE NULL END);
CREATE INDEX EQHUB.IDX_BBO_DES_FBI ON EQHUB.BBO_DESCRIPTIVE_DATA (CASE WHEN latest_version_flag = 'Y' THEN 1 ELSE NULL END);
For the second command (IDX_BBO_DES_FBI), when i query DBA_IND_EXPRESSIONS view, i found that Oracle has done some kind of QUERY TRANSFORMATION (?) and converted
FBI expression to CASE "LATEST_VERSION_FLAG" WHEN 'Y' THEN 1 ELSE NULL END.At the same time,EXPRESSION on first index is not changed.
Now,my question is what has made transformation to occure only for second index.
I also found that inspite of highly SELECTIVE nature of both the indexes, only SECOND index is being used by CBO (for which trasnformation occured)
and IDX_BBO_WRT_DES_FBI is not being used(FTS is happening instead).
Query is using same expression for both the tables as
(CASE WHEN latest_version_flag = 'Y' THEN 1 ELSE NULL END)=1
INDEX_NAME TABLE_NAME COLUMN_EXPRESSION
IDX_BBO_WRT_DES_FBI BBO_WARRANT_PRICING CASE WHEN "LATEST_VERSION_FLAG"='Y' THEN 1 ELSE NULL END
IDX_BBO_DES_FBI BBO_DESCRIPTIVE_DATA CASE "LATEST_VERSION_FLAG" WHEN 'Y' THEN 1 ELSE NULL ENDI read that expression should be evaluated including CASE of characters and spaces in query.Is that true?
Appreciating responses in advance.Randolf.
It's a shame that I forgot to look into the full execution plan information to check how Oracle really handles my queries.
Look here(edited for clarity):
explain plan for
select /*+ case1 ordered use_nl(x, y) */ count(case c1
when '1' then 1
when '2' then 2
when '3' then 3
else 4
end) from
(select level from dual connect by level <= 300000) x,
(select
from t1
) y;
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 2 | 5 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 2 | | |
| 2 | NESTED LOOPS | | 3 | 6 | 5 (0)| 00:00:01 |
| 3 | VIEW | | 1 | | 2 (0)| 00:00:01 |
| 4 | CONNECT BY WITHOUT FILTERING| | | | | |
| 5 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL | T1 | 3 | 6 | 3 (0)| 00:00:01 |
Column Projection Information (identified by operation id):
1 - (#keys=0) COUNT(CASE WHEN "T1"."C1"='1' THEN 1 WHEN "T1"."C1"='2' THEN
2 WHEN "T1"."C1"='3' THEN 3 ELSE 4 END )[22]
2 - (#keys=0) "T1"."C1"[CHARACTER,1]
4 - "DUAL".ROWID[ROWID,10], LEVEL[4]
5 - "DUAL".ROWID[ROWID,10]
6 - "T1"."C1"[CHARACTER,1]
32 rows selected.
explain plan for select /*+ case2 ordered use_nl(x, y) */ count(case
when c1 = '1' then 1
when c1 = '2' then 2
when c1 = '3' then 3
else 4
end) from
(select level from dual connect by level <= 300000) x,
(select
from t1
) y;
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 2 | 5 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 2 | | |
| 2 | NESTED LOOPS | | 3 | 6 | 5 (0)| 00:00:01 |
| 3 | VIEW | | 1 | | 2 (0)| 00:00:01 |
| 4 | CONNECT BY WITHOUT FILTERING| | | | | |
| 5 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL | T1 | 3 | 6 | 3 (0)| 00:00:01 |
Column Projection Information (identified by operation id):
1 - (#keys=0) COUNT(CASE WHEN "T1"."C1"='1' THEN 1 WHEN "T1"."C1"='2' THEN
2 WHEN "T1"."C1"='3' THEN 3 ELSE 4 END )[22]
2 - (#keys=0) "T1"."C1"[CHARACTER,1]
4 - "DUAL".ROWID[ROWID,10], LEVEL[4]
5 - "DUAL".ROWID[ROWID,10]
6 - "T1"."C1"[CHARACTER,1]As you exactly mentioned, I was executing different SQL but actually same queries!
Thanks for pointing my flaws.
PS) OP, forgive me for bothering you with off-topic things. :)
================================
Dion Cho - Oracle Performance Storyteller
http://dioncho.wordpress.com (english)
http://ukja.tistory.com (korean)
================================
Edited by: Dion_Cho on Feb 10, 2009 5:45 AM
Typo -
Function-based indexes don't seem to work in Oracle 8.1.5?
Hi,
What gives? What am I doing wrong? I have a table AIRPORT with a column (varchar2(64)) which I have specified a function based index for, but I can't get SQL wueries to use it!!!! the following SQL executes a FULL TABLE SCAN:
select /*+ index (a idx_upper_cityname) */ *
from airport a
where nls_upper(cityName) = 'dfdf'
...as does...
select *
from airport a
where nls_upper(cityName) = 'dfdf'
Table and index code is as follows:
CREATE TABLE airport
id NUMBER NOT NULL,
citycode VARCHAR2(3) NOT NULL,
cityname VARCHAR2(64) NOT NULL,
state VARCHAR2(2),
country VARCHAR2(2) NOT NULL,
region CHAR(1),
airportcode VARCHAR2(3) NOT NULL,
airportname VARCHAR2(64),
code VARCHAR2(4)
drop index idx_upper_cityname
CREATE INDEX idx_upper_cityname ON airport nls_upper(substr(cityName, 0, 64) )
Environment is as follows:
Oracle8i v8.1.5 running on WinNT v4.0 (SP 5)
Client is running on the same machine
thanks in advance,
AlexanderNew data point: when I set the handler in my logging.properties file thusly,
org.apache.catalina.core.ContainerBase.[Catalina].[info-dev].[/infoisland].level = ALL
org.apache.catalina.core.ContainerBase.[Catalina].[info-dev].[/infoisland].handlers = java.util.logging.ConsoleHandlerI get 0 bytes in the info-dev log (which used to have the aforementioned expception in it). Where is my console going?
Maybe you are looking for
-
Cancel/delete transfer order
Hello Guys, I would like to ask on how to cancel/delete a certain transfer order wherein the outbound delivery which is linked to it has already been deleted in the system? When I tried to execute transaction LT15, it gives the following error messag
-
Space Designer 'hangs' Logic * when choosing preset
Hello All, This is my first post!! I've just purchased a new Intel Mac 8 core with 8 gig of ram - great machine and can seem to handle many plugs. I seem to have a problem - when changing a preset in Space Designer it hangs Logic, I force quit and ha
-
A program called BING seems to have inbedded itself and cannot unenstall or delete.
The program does not allow my home page to come up at start up. Found it in the root directory with Firefox and deleted it but must be imbedded in Firefox because it still starts up with BING home page.
-
Locked out of ipad forgot passcode
ive manage to lock my ipad and do not kno what the passcode is. is there a way to reset without itunes? tried that without any luck thanks
-
Iphone 4 cannot send or receive text message
I just got my iphone 4 yeaterday. Everything works fine except for the text messages. I can make and receive call, but cannot send or receive text messages. Does anyone have this problam? After I hit "send", it sounds message sent successfully, but m