Home » RDBMS Server » Performance Tuning » Why *is* my index used? (oracle 19c Linux)
Why *is* my index used? [message #686609] |
Sun, 23 October 2022 06:29  |
Andrey_R
Messages: 441 Registered: January 2012 Location: Israel
|
Senior Member |
|
|
Hi all,
I've prepared a testcase, where I have a table, which I made sure to have the same value for column TABLE_NAME:
SQL> SET TIMING ON LINES 900 PAGES 20000
SQL>
SQL> DROP TABLE TEST PURGE;
Table dropped.
Elapsed: 00:00:02.82
SQL>
SQL>
SQL> CREATE TABLE TEST
2 as select TABLE_NAME , NUM_ROWS, LAST_ANALYZED, IOT_NAME,PARTITIONED,LOGGING from dba_tables;
Table created.
Elapsed: 00:00:17.39
SQL>
SQL>
SQL> select count(*) from TEST;
COUNT(*)
----------
19212
Elapsed: 00:00:00.07
SQL>
SQL> UPDATE TEST set TABLE_NAME = 'COMMON';
19212 rows updated.
Elapsed: 00:00:00.43
SQL> commit;
Commit complete.
Then I've created an index on this column, and made sure statistics and histograms are collected on both table and indexes ( cascade ):
SQL>
SQL> CREATE INDEX TESTIND ON TEST ( TABLE_NAME ) ;
Index created.
Elapsed: 00:00:00.56
SQL>
SQL> EXEC dbms_stats.gather_table_stats ( ownname => user, tabname => 'TEST', method_opt => 'FOR COLUMNS TABLE_NAME' , estimate_percent => 100, CASCADE => TRUE );
PL/SQL procedure successfully completed.
Elapsed: 00:00:01.19
SQL>
SQL>
SQL> select histogram from USER_TAB_COLUMNS WHERE COLUMN_NAME = 'TABLE_NAME' AND TABLE_NAME = 'TEST';
HISTOGRAM
---------------
FREQUENCY
Elapsed: 00:00:00.36
Now, I would expect that the plan table output will show me AN INDEX SCAN when I am querying the selective value:
SQL> SET AUTOTRACE TRACEONLY EXPLAIN
SQL>
SQL>
SQL> SELECT * FROM TEST WHERE TABLE_NAME = 'SUPER_SELECTIVE';
Elapsed: 00:00:00.25
Execution Plan
----------------------------------------------------------
Plan hash value: 2046642159
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 26 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TEST | 1 | 26 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TESTIND | 1 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("TABLE_NAME"='SUPER_SELECTIVE')
SQL>
SQL>
So far so good.
However, I would also expect it to perform A FULL TABLE SCAN when I give it the absolute non selective condition in the WHERE CLAUSE:
SQL> SELECT * FROM TEST WHERE TABLE_NAME = 'COMMON';
Elapsed: 00:00:00.55
Execution Plan
----------------------------------------------------------
Plan hash value: 2046642159
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11 | 286 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TEST | 11 | 286 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TESTIND | | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("TABLE_NAME"='COMMON')
SQL>
Still INDEX RANGE SCAN..
Questions:
1. Why ?
2. How can I ( or can I at all ) make the optimizer "realize" it's better off doing a FTS ( without plan stability tools usage ) ?
Many thanks in advance
Andrey
|
|
|
|
|
|
Re: Why *is* my index used? [message #686623 is a reply to message #686622] |
Sat, 29 October 2022 10:51  |
John Watson
Messages: 8976 Registered: January 2010 Location: Global Village
|
Senior Member |
|
|
You must have something odd in your environment. I've already made couple of suggestions. You could try
1. Drop any copies of the plan_table
2. Delete all your object statistics
3. Gather stats with default sample size (you should NEVER use estimate_percent=100) and method_opt=>'for all columns size skewonly'
3. Run the statement, then use dbms_xplan.display_cursor to see what actually happens
|
|
|
Goto Forum:
Current Time: Fri May 02 22:35:10 CDT 2025
|