Why the feature multiple column indexes using index skip scan?

Hi all

I have just been hired by a new company and I explored its database infrastructure. Interestingly, I see several function based indexed column used for all the tables. I found it strange, but they said ' we use Axapta to connect Axapta with Oracle, function index according to should be used to improve performance. Therefore, our DBAs create several indexes of feature based for each table in the database. "Unfortunately, I can not judge their business logic.

My question is, I just created similar to my local database tables in order to understand the behavior of the function index according to several columns. In order to create indexes of based function (substr and nls_lower), I have to declare the columns as varchars2. Because in my business our DBAs had created a number of columns as a varchar2 data type. I created two excatly same table for my experience. I create miltiple function according to index on the my_first table, and then I create several normal index on the my_sec table. The interesting thing is, index skip scan cannot be performed on more than one basic function index (table my_first). However, it can be performed to normal several index on my_sec table. I hope that I have to express myself clearly.

Note: I also ask the logic of the rule function based index, they said when they index a column they don't ((column length) * 2 + 1) formula. For example, I want to create indexes on the zip code column, column data type VARCHAR2 (3), so I have to use 3 * 2 + 1 = 7, (substr (nls_lower (areacode), 1, 7). substr (nls_lower ()) notation is used nested for any function function index. I know that these things are very illogical, but they told me, they use this type of implementation for Axapta.

Anyway, in this thread, my question is reletad to function function with index index skip scan, not logical bussiness, because I can not change the business logic.

Also, can you please give hints or clues for multiple function based indexes?

Thanks for your help.


SQL > create table my_first as select '201' codeZone, to_char (100 + rownum) account_num, dbms_random.st
Ring name ('A', 10) from dual connect by level < = 5000;

Table created.

SQL > create table my_sec as select '201' codeZone, to_char (100 + rownum) account_num, dbms_random.st

Ring name ('A', 10) from dual connect by level < = 5000;

Table created.

SQL > alter table my_first change account_num varchar2 (12);

Modified table.


SQL > alter table my_sec change account_num varchar2 (12);

Modified table.

SQL > alter table my_first change codeZone VARCHAR2 (3);

Modified table.

SQL > alter table my_sec change codeZone VARCHAR2 (3);

Modified table.

SQL > create index my_first_i on my_first (substr (nls_lower (areacode), 1, 7), substr (nls_lower (account_num), 1, 15));

The index is created.

SQL > create index my_sec_i on my_sec (area code, account_num);

The index is created.

SQL > analyze table my_first computing statistics for all columns indexed for all indexes.

Parsed table.

SQL > analyze table my_sec computing statistics for all columns indexed for all indexes.

Parsed table.

SQL > exec dbms_stats.gather_table_stats (USER, 'MY_FIRST');

PL/SQL procedure successfully completed.

SQL > exec dbms_stats.gather_table_stats (USER, 'MY_SEC');

PL/SQL procedure successfully completed.

SQL > my_first desc;
Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
CODEZONE VARCHAR2 (3)
ACCOUNT_NUM VARCHAR2 (12)
NAME VARCHAR2 (4000)

SQL > desc my_sec
Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
CODEZONE VARCHAR2 (3)
ACCOUNT_NUM VARCHAR2 (12)
NAME VARCHAR2 (4000)

SQL > select * from my_sec where account_num = '4000';


Execution plan
----------------------------------------------------------
Hash value of plan: 1838048852

--------------------------------------------------------------------------------
--------

| ID | Operation | Name | Lines | Bytes | Cost (% CPU). TI
me |

--------------------------------------------------------------------------------
--------

|   0 | SELECT STATEMENT |          |     1.    19.     3 (0) | 00
: 00:01 |

|   1.  TABLE ACCESS BY INDEX ROWID | MY_SEC |     1.    19.     3 (0) | 00
: 00:01 |

|*  2 |   INDEX SKIP SCAN | MY_SEC_I |     1.       |     2 (0) | 00
: 00:01 |

--------------------------------------------------------------------------------
--------


Information of predicates (identified by the operation identity card):
---------------------------------------------------

2 - access ("ACCOUNT_NUM" = '4000')
Filter ("ACCOUNT_NUM" = '4000')


Statistics
----------------------------------------------------------
1 recursive calls
0 db block Gets
Gets 7 compatible
0 physical reads
0 redo size
543 bytes sent via SQL * Net to client
384 bytes received via SQL * Net from client
2 SQL * Net back and forth to and from the client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL > select * from my_first where substr (nls_lower (account_num), 1: 25) = '4000';


Execution plan
----------------------------------------------------------
Hash value of plan: 1110109060

------------------------------------------------------------------------------
| ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |          |     1.    20.     9 (12) | 00:00:01 |
|*  1 |  TABLE ACCESS FULL | MY_FIRST |     1.    20.     9 (12) | 00:00:01 |
------------------------------------------------------------------------------

Information of predicates (identified by the operation identity card):
---------------------------------------------------

1 Filter (SUBSTR (NLS_LOWER ("MY_FIRST". "" "" ACCOUNT_NUM")(, 1, 15) ="4000"
AND SUBSTR (NLS_LOWER ("ACCOUNT_NUM"), 1, 25) = '4000')


Statistics
----------------------------------------------------------
15 recursive calls
0 db block Gets
Gets 26 consistent
0 physical reads
0 redo size
543 bytes sent via SQL * Net to client
384 bytes received via SQL * Net from client
2 SQL * Net back and forth to and from the client
0 sorts (memory)
0 sorts (disk)
1 rows processed

SQL > Select / * + INDEX_SS (MY_FIRST) * / * from my_first where substr (nls_lower (account_num), 1: 25) = '4000';


Execution plan
----------------------------------------------------------
Hash value of plan: 2466066660

--------------------------------------------------------------------------------
----------

| ID | Operation | Name | Lines | Bytes | Cost (% CPU).
Time |

--------------------------------------------------------------------------------
----------

|   0 | SELECT STATEMENT |            |     1.    20.    17 (6) |
00:00:01 |

|*  1 |  TABLE ACCESS BY INDEX ROWID | MY_FIRST |     1.    20.    17 (6) |
00:00:01 |

|*  2 |   INDEX SCAN FULL | MY_FIRST_I |     1.       |    16 (7) |
00:00:01 |

--------------------------------------------------------------------------------
----------


Information of predicates (identified by the operation identity card):
---------------------------------------------------

1 - filter (SUBSTR (NLS_LOWER ("ACCOUNT_NUM"), 1, 25) = '4000')
2 - access (SUBSTR (NLS_LOWER ("ACCOUNT_NUM"), 1, 15) = '4000')
Filter (substr (NLS_LOWER ("ACCOUNT_NUM"), 1, 15) = '4000')


Statistics
----------------------------------------------------------
15 recursive calls
0 db block Gets
857 consistent gets
0 physical reads
0 redo size
543 bytes sent via SQL * Net to client
384 bytes received via SQL * Net from client
2 SQL * Net back and forth to and from the client
0 sorts (memory)
0 sorts (disk)
1 rows processed

Check MoS for a bug with the FBI and Skip Scan - it sounds like it could be a bug.

On 11.2.0.4 with your sample code 10053 trace shows the optimizer whereas an index FULL scan to the point where she should consider an index SKIP scan for "unique table path".

A person with 12.1.0.1 practice would like to run your test and see if it's fixed in this version.

Concerning

Jonathan Lewis

Tags: Database

Similar Questions

  • Question on the composite index and index skip scan

    Hello
    I have a confusion.
    I read the post of Burleson on the column of the composite index command (http://www.dba-oracle.com/t_composite_index_multi_column_ordering.htm) where he writes that

    «.. . for composite indexes the most restrictive value of the column (the column with the highest unique values) should be made first to cut down the result set in... »


    But 10g performance tuning book tells the subject INDEX SKIP SCAN:

    "... Index scan Skip allows a composite index that is logically divided into smaller subindex. In Dumpster
    scanning, the first column in the composite index is not specified in the query. In other words, it is ignored.
    The number of logic subindex is determined by the number of distinct values in the first column.

    Skip scanning is advantageous if there are few distinct values in the main column of the composite index and many distinct values in the key do not tip of the index... »

    If design us a composite index according to what said Burleson, then how can we take advantage of index skip scan. These two staements to oppose each other, Don't they?

    Can someone explain this?

    Even if you're not skip scanning, it is best to put the column with less distinct values in the main column of the index.

    If a query specifies two key as predicates of equality columns, it doesn't really matter how columns are sorted in the index.
    If a query specifies a range on a key column, it is most likely on the second column of the index.

    BTW, sometimes even a column 3 or the index of the column 4 is useful. In order to not restrict simply yourself in 2 columns. However, do not create too many clues - especially if there is overlap between the index.

    Hemant K Collette

  • doubt about the Index Skip Scan

    Hi all

    I read the setting of Oracle performance guide (Version 11.2 Chapter 11). I just want to see index skip scan with an example. I created a table called t and inserted the test data. When I asked the table optimizer did not use the index skip scan path.

    Can you please let me know what mistake I am doing here.

    Thanks a lot for your help in advance.

    SQL > create table t (empno number
    2, ename varchar2 (2000)
    3, varchar2 (1) sex
    4, email_id varchar2 (2000));

    Table created

    SQL >
    SQL >-test data
    SQL > insert into t
    2 level, select "suri" | (level), ','suri.king' | level | ' @gmail.com'
    3 double
    4. connect by level < = 20000
    5.

    20000 lines inserted

    SQL >
    SQL > insert into t
    2 Select level + 20000, 'surya ' | (level + 20000), 'F', 'surya.princess'. (level + 20000) : ' @gmail.com '
    3 double
    4. connect by level < = 20000
    5.

    20000 lines inserted

    SQL > create index t_gender_email_idx on t (gender, email_id);

    Index created

    SQL > explain the plan for
    2 Select
    3 t
    4 where email_id = "[email protected]";

    He explained.

    SQL > select *.
    table 2 (dbms_xplan.display);

    PLAN_TABLE_OUTPUT
    ----------------------------------------------------------------------------------------------------------------
    Hash value of plan: 1601196873

    --------------------------------------------------------------------------
    | ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |
    --------------------------------------------------------------------------


    |   0 | SELECT STATEMENT |      |     4.  8076 |   103 (1) | 00:00:02 |
    |*  1 |  TABLE ACCESS FULL | T    |     4.  8076 |   103 (1) | 00:00:02 |
    --------------------------------------------------------------------------

    Information of predicates (identified by the operation identity card):
    ---------------------------------------------------

    1 - Filter ("EMAIL_ID"= "[email protected]")

    Note
    -----
    -dynamic sample used for this survey (level = 2)

    17 selected lines.

    See you soon,.

    Suri

    You have just demonstrated how your execution plan gets screwed up if you do not have your statistics

    SQL > create table t
    () 2
    3 empno number
    4, ename varchar2 (2000)
    5, varchar2 (1) sex
    6, email_id varchar2 (2000)
    7  );

    Table created.

    SQL > insert into t
    2 Select level, "suri" | (level), ', 'suri.king'| level | ' @gmail.com'
    3 double
    4. connect by level<=>
    5.

    20000 rows created.

    SQL > insert into t
    2 Select level + 20000, 'surya ' | (level + 20000), 'F', 'surya.princess'. (level + 20000) : ' @gmail.com'
    3 double
    4. connect by level<=>
    5.

    20000 rows created.

    SQL > create index t_gender_email_idx on t (gender, email_id);

    The index is created.

    SQL > set autotrace traceonly explain
    SQL >
    SQL > select *.
    2 t
    3 where email_id = "[email protected]";

    Execution plan
    ----------------------------------------------------------
    Hash value of plan: 2153619298

    --------------------------------------------------------------------------
    | ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT |      |     3.  6057.    79 (4) | 00:00:01 |
    |*  1 |  TABLE ACCESS FULL | T    |     3.  6057.    79 (4) | 00:00:01 |
    --------------------------------------------------------------------------

    Information of predicates (identified by the operation identity card):
    ---------------------------------------------------

    1 - Filter ("EMAIL_ID"= "[email protected]")

    Note
    -----
    -dynamic sampling used for this statement

    SQL > exec dbms_stats.gather_table_stats (user, 't', cascade-online true)

    PL/SQL procedure successfully completed.

    SQL > select *.
    2 t
    3 where email_id = "[email protected]";

    Execution plan
    ----------------------------------------------------------
    Hash value of plan: 2655860347

    --------------------------------------------------------------------------------------------------
    | ID | Operation | Name               | Lines | Bytes | Cost (% CPU). Time |
    --------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT |                    |     1.    44.     1 (0) | 00:00:01 |
    |   1.  TABLE ACCESS BY INDEX ROWID | T                  |     1.    44.     1 (0) | 00:00:01 |
    |*  2 |   INDEX SKIP SCAN | T_GENDER_EMAIL_IDX |     1.       |     1 (0) | 00:00:01 |
    --------------------------------------------------------------------------------------------------

    Information of predicates (identified by the operation identity card):
    ---------------------------------------------------

    2 - access ("EMAIL_ID"= '[email protected]')
    filter ("EMAIL_ID"= "[email protected]")

    SQL >

  • INDEX RANGE SCAN against INDEX SKIP SCAN

    Dear,

    Let me introduce you to the model, and then I'll ask my question
    SQL> select * from v$version;
    
    BANNER
    ----------------------------------------------------------------
    Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
    PL/SQL Release 10.2.0.5.0 - Production
    CORE    10.2.0.5.0      Production
    TNS for Solaris: Version 10.2.0.5.0 - Production
    NLSRTL Version 10.2.0.5.0 - Production
    
    SQL> create table t1
      2     as select rownum                  id1,
      3      mod(rownum,1000)                  id2,
      4      lpad(rownum,10,'0')              small_vc,
      5      rpad('x',1000)                   padding
      6  from dual
      7  connect by level <= 10000;
    
    Table created.
    
    SQL> create index t1_ind_id1 on t1(id1);
    
    Index created.
    
    SQL> create index t1_ind_id2 on t1(id2, id1);
    
    Index created.
    
    SQL> exec dbms_stats.gather_table_stats(user, 't1', cascade => true);
    
    PL/SQL procedure successfully completed.
    
    SQL> select index_name, num_rows, clustering_factor
      2  from user_indexes
      3  where index_name in ('T1_IND_ID1','T1_IND_ID2');
    
    INDEX_NAME                       NUM_ROWS CLUSTERING_FACTOR
    ------------------------------ ---------- -----------------
    T1_IND_ID1                          10000              1429
    T1_IND_ID2                          10000             10000
    
    
    SQL> select *
      2  from t1
      3  where id1=6;
    
     Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2367654148
    
    ------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |            |     1 |  1019 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1         |     1 |  1019 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | T1_IND_ID1 |     1 |       |     1   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("ID1"=6)
    So far so good.

    What I want is to know how I can reproduce an example of real life where an index skip scan has been chosen by the CBO despite the presence of the index 'adequate '.

    Here, below, I tried several examples
    SQL> alter index t1_ind_id1 unusable;
    
    Index altered.
    
    SQL> select *
      2  from t1
      3  where id1=6;
    
      Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2497247906
    
    ------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |            |     1 |  1019 |  1004   (1)| 00:00:03 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1         |     1 |  1019 |  1004   (1)| 00:00:03 |
    |*  2 |   INDEX SKIP SCAN           | T1_IND_ID2 |     1 |       |  1003   (1)| 00:00:03 |
    ------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("ID1"=6)
           filter("ID1"=6)
    It's predictable. Let replace them the usable index and change its grouping factor
    SQL> alter index t1_ind_id1 rebuild;
    
    Index altered.
    
    SQL> select *
      2  from t1
      3  where id1=6;
    
         
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2367654148
    
    ------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |            |     1 |  1019 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1         |     1 |  1019 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | T1_IND_ID1 |     1 |       |     1   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("ID1"=6)
    
    SQL> exec dbms_stats.set_index_stats(user, 'T1_IND_ID1',clstfct => 20000);
    
    PL/SQL procedure successfully completed.
    
    SQL> select index_name, num_rows, clustering_factor
      2  from user_indexes
      3  where index_name in ('T1_IND_ID1','T1_IND_ID2');
    
    INDEX_NAME                       NUM_ROWS CLUSTERING_FACTOR
    ------------------------------ ---------- -----------------
    T1_IND_ID1                          10000             20000
    T1_IND_ID2                          10000             10000
    
    
    SQL> select *
      2  from t1
      3  where id1=6;
    
        
    Execution Plan
    ------------------------------------------------------------------------------------------
    Plan hash value: 2367654148
    ------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |            |     1 |  1019 |     3   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1         |     1 |  1019 |     3   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | T1_IND_ID1 |     1 |       |     1   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("ID1"=6)
    Still without success to produce an INDEX SKIP SCAN on T1_IND_ID2 in the presence of the T1_IND_ID1 index

    Any suggestions?

    Thank you

    Mohamed Houri
    www.hourim.WordPress.com

    What I want is to know how I can reproduce an example of real life where an index skip scan has been chosen by the CBO despite the presence of the 'adequate' index

    If, on behalf of the investigation, trying to 'force' the index skip scan, you must do two things:

    1. change the factor of grouping of TI_IND_ID1 to make it more expensive.

    While Hemant and Nikolay make good points on the fact that the grouping factor SHOULD BE irrelevant for a search of a single line, you are using a non-unique index is still part of the calculation of costs for a range scan.

    It had been a unique index so the factor of grouping of piracy would have been ineffective.

    But because only the cost calculation involves selectivity * factor clustering, you must change it by an order of magnitude (relevant to num_distinct obviously) to make significant change.

    For example:

    SQL> exec dbms_stats.set_index_stats(user, 'T1_IND_ID1',clstfct => 20000000);
    
    PL/SQL procedure successfully completed.
    
    SQL> explain plan for
      2  select /*+ index(t1 t1_ind_id1) */ *
      3  from t1
      4  where id1=6;
    
    Explained.
    
    SQL> select * from table(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    ---------------------------------------------------------------------------------------------------------
    Plan hash value: 3180815200
    
    ------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |            |     1 |  1019 |  2002   (1)| 00:00:25 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1         |     1 |  1019 |  2002   (1)| 00:00:25 |
    |*  2 |   INDEX RANGE SCAN          | T1_IND_ID1 |     1 |       |     1   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("ID1"=6)
    
    14 rows selected.
    
    SQL>
    

    This pushes the cost of analysis of the range up above the table scan complete:

    SQL> explain plan for
      2  select *
      3  from t1
      4  where id1=6;
    
    Explained.
    
    SQL>  select * from table(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    -----------------------------------------------------------------------------------------------
    Plan hash value: 3617692013
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |     1 |  1019 |   322   (1)| 00:00:04 |
    |*  1 |  TABLE ACCESS FULL| T1   |     1 |  1019 |   322   (1)| 00:00:04 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("ID1"=6)
    
    13 rows selected.
    
    SQL>
    

    So, now to the next step.

    2. we need to artificially reduce the cost of the analysis of Skip - and the best way to do that is by changing the separate issue of the main column in the index (currently 1000):

    SQL> begin
      2     DBMS_STATS.SET_COLUMN_STATS
      3     (ownname       => USER,
      4      tabname       => 'T1',
      5      colname       => 'ID2',
      6      partname      => NULL,
      7      stattab       => NULL,
      8      statid        => NULL,
      9      distcnt       => 1,
     10      density       => 1,
     11      nullcnt       => 0,
     12      srec          => NULL,
     13      avgclen       => 4,
     14      flags         => NULL,
     15      statown       => NULL,
     16      no_invalidate => FALSE,
     17      force         => TRUE);
     18  end;
     19  /
    
    PL/SQL procedure successfully completed.
    
    SQL> 
    

    As a Skip Scan is now taken over by default:

    SQL> explain plan for
      2  select *
      3  from t1
      4  where id1=6;
    
    Explained.
    
    SQL> select * from table(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    ---------------------------------------------------------------------------------------------------
    Plan hash value: 3198394326
    
    ------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |            |     1 |  1019 |     3   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1         |     1 |  1019 |     3   (0)| 00:00:01 |
    |*  2 |   INDEX SKIP SCAN           | T1_IND_ID2 |     1 |       |     2   (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("ID1"=6)
           filter("ID1"=6)
    
    15 rows selected.
    
    SQL>
    

    Hope this helps

    Published by: Dom Brooks on October 24, 2012 12:49
    Reformulated

  • Basic query - Index Skip Scan

    Hello

    I have a very basic question.

    I use Autotrace to check the Plan for this query

    Table definition:
    ------------------------------------
    create table tb_emp)
    sextype varchar2 (1).
    EmpID number
    );

    Array of values
    -----------------------------------------------
    insert into tb_emp values ('F', 98);
    insert into tb_emp values ('F', 100);
    insert into tb_emp values ('F', 102);
    insert into tb_emp values ('F', 104);
    insert into tb_emp values('M',101);
    insert into tb_emp values('M',103);
    insert into tb_emp values('M',105);
    commit;

    Index:
    -----------------------------------------------------------------------------
    create index EMP_SEXTYPE_EMP_IDX on tb_emp (SEXTYPE, empid);


    Query:
    --------------------------------------------------------------------------------------------------------------
    Select * from tb_emp where empid = 101;

    ---------------------------------------------------------------------------------------------------------------
    Execution plan
    ----------------------------------------------------------
    0 SELECT STATEMENT Optimizer = ALL_ROWS (cost = 0 card = 1 bytes = 15)
    1 INDEX 0 (COMPLETE ANALYSIS) OF 'EMP_SEXTYPE_EMP_IDX' (INDEX) (cost = 0 card = 1 bytes = 15)

    According to b14211 this should translate into an index Skip Scan,

    A pointer to what am I missing or other parameters that could affect the execution plan.
    Thank you and best regards,
    Ashish.

    The case of test used by you is not a real. With 7 records in a table is important if the optimizer goes for a systematic index scan or a full scan?

    make it a little big and try

    SQL> truncate table tb_emp
      2  /
    
    Table truncated.
    
    SQL> set autotrace off
    
    SQL> edit
    Wrote file afiedt.buf
    
      1  insert into tb_emp
      2  select decode(mod(level,2),0,'M','F'), level
      3    from dual
      4* connect by level <= 10000
    SQL> /
    
    10000 rows created.
    
    SQL> commit
      2  /
    
    Commit complete.
    
    SQL> select sextype, count(*) from tb_emp group by sextype
      2  /
    
    S   COUNT(*)
    - ----------
    M       5000
    F       5000
    
    SQL> exec dbms_stats.gather_table_stats(user,'TB_EMP',cascade=>true)
    
    PL/SQL procedure successfully completed.
    
    SQL> set autotrace traceonly explain
    SQL> select * from tb_emp where empid = 3000
      2  /
    
    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=1 Bytes=5)
       1    0   INDEX (SKIP SCAN) OF 'EMP_SEXTYPE_EMP_IDX' (INDEX) (Cost=3 Card=1 Bytes=5)
    
  • Oracle 10.2.0.4 Index on the time stamp column not used when SYSTIMESTAMP is used.

    Hello
    I have a table with a timestamp (6) column B. About 300000 rows in the tables...
    I created index 'idx' on column B.

    When I compare the column 'B' with systimestamp, it does not use the index, whereas if I compare 'B' with sysdate it uses the index.

    For example:
    Select count (*) in a b where clause < = sysdate;

    The above used the subscript "idx" and executed in 1 second

    Select count (*) in a b where clause < = systimestamp;

    The foregoing does not use the index and performed in 19 seconds.

    Any clue?

    Thanks in advance

    Oracle uses the internal functions when you use SYSTIMESTAMP:

    Work around is to use TO_TIMESTAMP as shown below... Or define a function based index...

    You can check the performance querying against a column "TIMESTAMP WITH time ZONE SCHEDULE" issue link too

    SQL> create table a(b timestamp(6));
    
    Table created.
    
    SQL> insert into a
      2  select systimestamp+(level/24) from dual connect by level <= 30000;
    
    30000 rows created.
    
    SQL> commit;
    
    Commit complete.
    
    SQL> create index ndx on a(b);
    
    Index created.
    
    SQL> explain plan for
      2  select count(*) from a where b <= sysdate;
    
    Explained.
    
    SQL> select * from table(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    Plan hash value: 3858831102
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |     1 |    13 |     1   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE   |      |     1 |    13 |            |          |
    |*  2 |   INDEX RANGE SCAN| NDX  |     1 |    13 |     1   (0)| 00:00:01 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("B"<=SYSDATE@!)
    
    Note
    -----
       - dynamic sampling used for this statement
    
    18 rows selected.
    
    SQL> explain plan for
      2  select count(*) from a where b <= systimestamp;
    
    Explained.
    
    SQL>  select * from table(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    Plan hash value: 3918351354
    
    ---------------------------------------------------------------------------
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |     1 |    13 |    20  (15)| 00:00:01 |
    |   1 |  SORT AGGREGATE    |      |     1 |    13 |            |          |
    |*  2 |   TABLE ACCESS FULL| A    |     1 |    13 |    20  (15)| 00:00:01 |
    ---------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - filter(SYS_EXTRACT_UTC(INTERNAL_FUNCTION("B"))<=SYS_EXTRACT_UTC(S
                  YSTIMESTAMP(6)))
    
    Note
    -----
       - dynamic sampling used for this statement
    
    19 rows selected.
    
    --"Just tried using TO_TIMESTAMP"
    
    SQL> explain plan for
      2  select count(*) from a where b <= to_timestamp(systimestamp);
    
    Explained.
    
    SQL>
    SQL> select * from table(dbms_xplan.display);
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    Plan hash value: 3858831102
    
    --------------------------------------------------------------------------
    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |      |     1 |    13 |     2   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE   |      |     1 |    13 |            |          |
    |*  2 |   INDEX RANGE SCAN| NDX  |     4 |    52 |     2   (0)| 00:00:01 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("B"<=TO_TIMESTAMP(TO_CHAR(SYSTIMESTAMP(6))))
    
    14 rows selected.
    

    Published by: JAC on October 23, 2012 11:18

  • How to view the line of columns without using the pivot keyword

    Hello
    could someone help me how to display lines in columns without using the keyword pivot and actuall is my scenario, iam having two tables with names and examples of data is shown below

    MIDDLE MINAME TASKID TASKNAME IDENTIFICATION PROJECT

    1 PROJ1 1 AA 100 PR1_TASK1
    1 PROJ1 3 CC PR1_TASK3 102
    1 PROJ1 DD 4 103 PR1_TASK4
    1 PROJ1 EE 5 104 PR1_TASK5
    1 PROJ1 6 105 FF PR1_TASK6
    2 PROJ2 EE 5 114 PR2_TASK1
    2 PROJ2 6 115 FF PR2_TASK2
    2 PROJ2 GG 7 116 PR2_TASK3
    2 PROJ2 HH 8 117 PR2_TASK4
    2 PROJ2 9 118 PR2_TASK5 JJ
    2 PROJ2 KK 10 119 PR2_TASK6
    2 PROJ2 1 AA PR2_TASK7 120


    The output should show the project and County of tasks at a given stage as shown below

    project AA BB CC DD EE FF GG HH JJ KK
    1 2 0 1 5 3 2 0 2 1 0
    2 1 2 0 2 1 0 2 4 3 1


    Thanks in advance,
    VVR
    CREATE TABLE pivot_test (
    ID           NUMBER,
    PROJECT      VARCHAR2(10),
    MID          NUMBER,
    MINAME       VARCHAR2(5),
    TASKID       NUMBER,
    TASKNAME     VARCHAR2(10)
    );
    
    INSERT INTO pivot_test VALUES (1, 'PROJ1', 1,  'AA', 100, 'PR1_TASK1');
    INSERT INTO pivot_test VALUES (1, 'PROJ1', 3,  'CC', 102, 'PR1_TASK3');
    INSERT INTO pivot_test VALUES (1, 'PROJ1', 4,  'DD', 103, 'PR1_TASK4');
    INSERT INTO pivot_test VALUES (1, 'PROJ1', 5,  'EE', 104, 'PR1_TASK5');
    INSERT INTO pivot_test VALUES (1, 'PROJ1', 6,  'FF', 105, 'PR1_TASK6');
    INSERT INTO pivot_test VALUES (2, 'PROJ2', 5,  'EE', 114, 'PR2_TASK1');
    INSERT INTO pivot_test VALUES (2, 'PROJ2', 6,  'FF', 115, 'PR2_TASK2');
    INSERT INTO pivot_test VALUES (2, 'PROJ2', 7,  'GG', 116, 'PR2_TASK3');
    INSERT INTO pivot_test VALUES (2, 'PROJ2', 8,  'HH', 117, 'PR2_TASK4');
    INSERT INTO pivot_test VALUES (2, 'PROJ2', 9,  'JJ', 118, 'PR2_TASK5');
    INSERT INTO pivot_test VALUES (2, 'PROJ2', 10, 'KK', 119, 'PR2_TASK6');
    INSERT INTO pivot_test VALUES (2, 'PROJ2', 1,  'AA', 120, 'PR2_TASK7');
    
    SELECT ID as PROJECT,
           SUM(DECODE(miname, 'AA', 1, 0)) AS AA,
           SUM(DECODE(miname, 'BB', 1, 0)) AS BB,
           SUM(DECODE(miname, 'CC', 1, 0)) AS CC,
           SUM(DECODE(miname, 'DD', 1, 0)) AS DD,
           SUM(DECODE(miname, 'EE', 1, 0)) AS EE,
           SUM(DECODE(miname, 'FF', 1, 0)) AS FF,
           SUM(DECODE(miname, 'GG', 1, 0)) AS GG,
           SUM(DECODE(miname, 'HH', 1, 0)) AS HH,
           SUM(DECODE(miname, 'JJ', 1, 0)) AS JJ,
           SUM(DECODE(miname, 'KK', 1, 0)) AS KK
    FROM   pivot_test
    GROUP BY ID;
    
    PROJECT AA BB CC DD EE FF GG HH JJ KK
    ------- -- -- -- -- -- -- -- -- -- --
          1  1  0  1  1  1  1  0  0  0  0
          2  1  0  0  0  1  1  1  1  1  1 
    
  • Why the battery fully charged but used for 5 minutes will be disabled it?

    Hello

    In fact I use iPad Air for 2 and a half years, but already had battery problem.i went to the premium Center in Penang service ask about it. Just give them the answer because the warranty is already so just may 1 to 1 change but must load RM1300 to change. Some can no longer repair. I feel unworthy because even if I bought the Sony Xperia Acro S used more than iPad but still better than the iPad battery. All my friends said that rarely face this kind of problem. How I'm going to support again once because of battery problem can't fix, and change must pay for the new ipad.

    Hello

    Because the warranty is over, you can buy one off replacement warranty

    But you have to pay part of the cost.

    You must make an appointment on apple store.

    See you soon

    Brian

  • Curious to know why the Intel graphics card is used by the PS

    The illness forced me to move a laptop at the moment and I bought a Dell XPS 15: i7, 16 GB RAM, intel and Nvidia graphics devices, screen UHD / 4 k. I've noticed that CC using the Intel display device:

    psdisplayusage.jpg

    .. .not the Nvidia 960 a M:

    displaydevices.jpg

    It surprises me.  In the past, I have had a problem with this kind of set up and had to uninstall or disable the function of Intel as well as CC will not work correctly.  In any case, not the device of 960 m would have more heft than Intel one?  Is the arrangement created by Dell?  CC seems ok with this configuration, except that it has more brush stutter when you paint as usual.  Can I disable the Intel device and let the 960 m to do the job?

    Grateful for any advice. Laptops are again for me...

    David

    A Nvidia card usually has a control panel

    Go to the control center and change the global settings to always use the Nvidia card or allow the use of specific graphics cards of the program and the value Photoshop.exe always use the Nvidia card here, now, Photoshop should detect the Nvidia card.

    Hope that helps

    Terri

  • index skip scan

    Hi all
    excerpt from the page of doc guide 11-18 of rel2 11g performance tuning:
    Skip scanning is advantageous when there are few distinct
    values in the leading column of the composite index and many distinct values in the
    nonleading key of the index
    Anyone could explain it means by "nonleading key of the index?

    Best regards
    Val

    The key to an index is all the columns included in the index. The 'leader' or keys are the first column in the index. So, with an index on col1, col2, col3, you could make a request like:

    select * from table
    where col1 = value
    

    and have it use the index for a range scan. In this case, col1 is the main key. You could also do:

    select * from table
    where col1 = value and
          col2 = value
    

    In this case, col1 and col2 run keys. However, something like:

    select * from table
    where col2 = value and
          col3 = value
    

    does not use the main key to the index. According to a number of factors, Oracle may be able to skip scan this index to respond to your request.

    John

  • Why the OCR &amp; voting disk group is maintenance name SCAN

    Hi all

    I installed 11g R2 Grid Infrastructure followed the unique database software. I have not yet created any database.

    When I opened asmca-> diskgroup, I see the diskgroup which I created during the installation of the grid. When I select this diskgroup-> View Serviced databases, which is the expected result? I assumed it to be empty. But, in my case, I see my Cluster name (SCAN) as the name of database and used space is. 26 GB. Can someone clarify the on it. Thanks in advance.

    Hello

    you've done a full grid (software + configuration) installation before the only software intallation of the db. During this process, you can create the asm instance and at least a single diskgroup, which holds the OCR and voting disks in the cluster. It is the diskgroup see you and it looks like you have named your cluster.

    Concerning

    Thomas

  • How to transpose the rows in multiple columns by using PivotTable

    I have 1 line containing 12 columns with the value "JAN", "FEB", "MAR", "J-1","F-1","M-1","J-2","F-2","M-2","J-3","F-3","M-3"

    I want to display like

    JAN J - 1 F - 1 M - 1
    FEB J - 2 F - 2 M - 2
    MAR F - 3 J - 3 M - 3

    How to achieve the foregoing?

    Today, you have only 3 months JAN, Feb, Mar. Is it always the same number of columns. What happens if several months ago we added this line?

    Your data is really coming from relational source or some sort of text file?

    There is a better way to do this in narrative using HTML mode, if your condition is just to show them in several lines and do some math.

    Go to Narrative display;

    In the prefix, use

    In the text box 'Story' add something like that



    As a suffix, use

    @1@4@7
    @2@5@8
    @3@6@9

    You can also add simple calculations like sum etc at the bottom of these lines as the overall totals.

    Kris

  • Consolidation of multiple columns by using the statement box

    Hello

    I have 4 columns

    Column_A, Column_B, Column_C, Column_D

    I created Column_E IE

    ALTER Table My_Table
    ADD)
    Column_E varchar2 (100)
    )

    Data in columns A - D are either 'Y', ' no or (null)

    What is necessary is the following: if it is a 'Y' in ONE of the columns A to D then place 'Y' in Column_E place in the case "n" in Column_E. This must be done for all the lines of my_table

    Thank you!!!

    Banner:
    Oracle Database 11 g Release 11.2.0.2.0 - 64 bit Production
    PL/SQL Release 11.2.0.2.0 - Production
    "CORE 11.2.0.2.0 Production."
    AMT for Linux: Version 11.2.0.2.0 - Production
    NLSRTL Version 11.2.0.2.0 - Production
    SQL> with test_data as
      2      (
      3      select 'N' a, 'N' b, 'N' c, 'N' d from dual union all
      4      select 'N' a, null b, 'Y' c, 'N' d from dual union all
      5      select null a, 'N' b, 'N' c, null d from dual union all
      6      select 'N' a, 'Y' b, 'N' c, 'N' d from dual union all
      7      select null a, null b, 'N' c, 'Y' d from dual
      8      )
      9  select t.*,
     10      case when instr(a||b||c||d,'Y') > 0 then  'Y' else 'N' end
     11  from test_data t;
    
    A B C D C
    - - - - -
    N N N N N
    N   Y N Y
      N N   N
    N Y N N Y
        N Y Y
    

    Please note that it helps if you provide test data as shown in this example.

  • Why the MAX aggregate function is used in SQL upon accession of the fields created in the designer?

    Of course Certified Developer, you can see the left join to include the fields in the SU_EXTENTION_DATA table. Why MAX is used when retrieving these values?

    ! Wont start-

    LEFT JOIN

    (SELECT

    REF_NO "REF."

    MAX (CASE WHEN EXTENSION_FIELD_REF = 500033 THEN VALUE_DATE END) "DOB",.

    MAX (CASE WHEN EXTENSION_FIELD_REF = VALUE_STRING END THEN 500034) "E_CONTACT."

    MAX (CASE WHEN EXTENSION_FIELD_REF = 500035 THEN VALUE_STRING END) "E_CONT_NO."

    MAX (CASE WHEN EXTENSION_FIELD_REF = 500036 THEN VALUE_TEXT END) "MED_HIST."

    MAX (CASE WHEN EXTENSION_FIELD_REF = 500037 THEN SELECT_TEXT END) 'PREF_CONTACT '.

    OF SU_EXTENSION_DATA

    LEFT JOIN SU_SELECT_VALUES ON

    SU_EXTENSION_DATA. VALUE_SELECT = SU_SELECT_VALUES. REF

    WHERE CORE_ENTITY = 5

    REF_NO GROUP) X ON AR_PERSON. REF = X.REF

    ! End custom-

    When you do you must include all the fields that have been selected as criteria for grouping the aggregation OR use false features like MAX (more likely it's easier way when the result field is expression).

  • Why the CD player replace default 'use Acrobat Pro' to open pdf files?

    Had to install the CD player to open online pdf files. Already have Acrobat Pro. After the installation of the drive of DC and despite repeated together "use this application to open pdf files" Acrobat Pro, CD player overrides this setting. Seems so new versions of programs... as, for example, Windows 10... are programmed by nerds who seem to think they know more about what a user wants to that user only. Sites now offer pdf files requiring a CD to open, but this version now seems to have the attitude "to hell with what you want to do." I want only to set Acrobat Pro as my default application to open pdf files. How can I do this? And, Adobe, why do you think that you know better than I what I want? < Nothing new, by the way; I had to do to make the script processing in PhotoShop, because it substitutes for my choices for the target files and your technicians had no idea how to solve this problem, with workarounds.

    Hi brucec3514345,

    Acrobat Reader DC has been defined as the once its installed default PDF Viewer, this is a behavior of design. However, you can change the default program, open Acrobat, navigate to the Edit-> Preferences-> General-> click "set as my default pdf reader.

    Click OK to confirm the changes.

    Kind regards
    Nicos

Maybe you are looking for