Oracle study notes composite index (XII)

1. Application in a separate query returns a lot of combinations query returns very little.

2. The combined sequential combination of the query, to fully consider the case of a separate inquiry

3. only non-equivalent range queries, the combination does not affect the performance index order 

4. The combination index column before the preferred sequence generally opposite the column equivalent query. 

5. Note that the combination index in combination with optimized conditions of about IN

! Composite index through the elements 

/ * 1. applicable in the case of a single query returns many records, suddenly after a combination of query returns a few records: 

   for example, where a master's degree = return a lot of records 
   , such as where career also returns a lot of cashiers = record 
   so no matter which conditions do query the index, are inappropriate. 
   However, if the degree is a master's, professional and at the same time is a cashier, she returned extremely rare. 
   So joint index so we can start to build up. 
* /    
   

/ * 2. The combined sequential combination inquiry, to consider the individual circumstances prefix query (or queries prefix index alone will not be effective or can only be used to jump index) 
   such as when you build id, object_type joint index, depending on consider a separate query where id = xxx much, or more than alone where object_type queries. 
* / 

. --3 only when no equivalent range queries, the combination index order does not affect the performance (such as where col1 = xxx and col2 = xxx , regardless COL1 + COL2 composition or compositions COL2 + COL1) 

drop purge Table T; 
Create Table T SELECT * from dba_objects AS; 
INSERT INTO SELECT * T from T; 
INSERT INTO SELECT * T from T; 
INSERT INTO SELECT * T from T; 
Update object_id = T SET rownum; 
the commit;
create index idx_id_type on t(object_id,object_type);
create index idx_type_id on t(object_type,object_id);
set autotrace off
alter session set statistics_level=all ;
set linesize 366

--性能和哪列在前没有什么差别
select /*+index(t,idx_id_type)*/ * from  t  where object_id=20  and object_type='TABLE';
select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
-----------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |      1 |        |      1 |00:00:00.01 |       5 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T           |      1 |     57 |      1 |00:00:00.01 |       5 |
|*  2 |   INDEX RANGE SCAN          | IDX_ID_TYPE |      1 |      9 |      1 |00:00:00.01 |       4 |
-----------------------------------------------------------------------------------------------------

select /*+index(t,idx_type_id)*/ * from  t  where object_id=20  and object_type='TABLE';
select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
Plan hash value: 3420768628

-----------------------------------------------------------------------------------------------------
| Id | Operation | the Name | Starts | E-the Rows | A-the Rows | A-Time | Buffers | 
SELECT / * index + (T, idx_id_type) * / T * from WHERE object_id> = 20 and object_id <2000 and object_type = 'TABLE';
-----------------------------------------------------------------------------------------------------
| 0 | the SELECT a STATEMENT | | 1 | | 1 | 00: 00: 00.01 | 5 | 
| 1 | TABLE ACCESS BY INDEX the ROWID | T | 1 | 57 | 1 | 00: 00: 00.01 | 5 | 
| * 2 | INDEX SCAN RANGE | IDX_TYPE_ID | 1 | 9 | 1 | 00: 00: 00.01 | 4 | 
------------------------------- -------------------------------------------------- -------------------- 

- 4. compositions generally preferred sequence index is equivalent to the column before the column opposite the query. (Combination index test case conditions ranging case, the condition is often unequal to be on the back, so that the front equivalent) 

SELECT * from Table (dbms_xplan.display_cursor (null, null, 'Last allstats ')); 
---------------------------------------------- -------------------------------------------------- -----
| Id  | Operation                   | Name        | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |      1 |        |    469 |00:00:00.01 |      86 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T           |      1 |     14 |    469 |00:00:00.01 |      86 |
|*  2 |   INDEX RANGE SCAN          | IDX_ID_TYPE |      1 |      1 |    469 |00:00:00.01 |      40 |
-----------------------------------------------------------------------------------------------------

select /*+index(t,idx_type_id)*/ *  from  t  where object_id>=20 and object_id<2000   and object_type='TABLE';
-------------------------------------------------- -------------------------------------------------- - 
| Id | Operation | the Name | Starts | E-the Rows | A-the Rows | A-Time | Buffers | 
-------------------------- -------------------------------------------------- ------------------------- 
| 0 | the SELECT a STATEMENT | | 1 | | 469 | 00: 00: 00.01 | 81 | 
| 1 | TABLE ACCESS the ROWID INDEX BY | T | 1 | 469 | 469 | 00: 00: 00.01 | 81 | 
|*  2 |   INDEX RANGE SCAN          | IDX_TYPE_ID |      1 |    469 |    469 |00:00:00.01 |      35 |
------------------------------ -------------------------------------------------- --------------------- 

--5 Note combination index optimization conditions on the composition of iN. 

- case. 1 

the UPDATE T = 20 is the SET the OBJECT_ID the WHERE ROWNUM <= 26000;
The UPDATE T the SET the OBJECT_ID = 21 is the WHERE the OBJECT_ID <> 20 is; 
a COMMIT; 
SET LINESIZE 1000 
SET pageSize. 1 
ALTER the session SET STATISTICS_LEVEL = All; 
SELECT / * + index (T, idx1_object_id) * / * from T WHERE object_type = 'TABLE' the AND the OBJECT_ID > = 20 OBJECT_ID the aND <= 21; 


. --6 case 2 
- is still on the optimization of iN (index case col1, col2, col3, and if not given query condition is cOL2, cOL3 test can only play a role) 

drop Table T purge; 
Create Table T AS SELECT * from dba_objects; 
the UPDATE T the SET the oBJECT_ID = 20 is the WHERE rOWNUM <= 26000;  
the UPDATE the OBJECT_ID the SET T = 21 WHERE OBJECT_ID <> 20;
the Update T SET object_id = 22 is WHERE rownum <= 10000; 
a COMMIT; 

Create index idx_union ON T (object_type, object_id, owner); 
SET OFF AUTOTRACE 
ALTER SET STATISTICS_LEVEL = All the session; 
SET LINESIZE 1000
select * from t where object_type='VIEW' and OWNER='LJB';
select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

select /*+INDEX(T,idx_union)*/ * from t T where object_type='VIEW' and OBJECT_ID IN (20,21,22) AND OWNER='LJB';
select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

  Partition table all kinds of polymerization optimization:

-- 范围分区示例
drop table range_part_tab purge;
--注意,此分区为范围分区

--例子1
create table range_part_tab (id number,deal_date date,area_code number,nbr number,contents varchar2(4000))
           partition by range (deal_date)
           (
           partition p_201301 values less than (TO_DATE('2013-02-01', 'YYYY-MM-DD')),
           partition p_201302 values less than (TO_DATE('2013-03-01', 'YYYY-MM-DD')),
           partition p_201303 values less than (TO_DATE('2013-04-01', 'YYYY-MM-DD')),
           partition p_201304 values less than (TO_DATE('2013-05-01', 'YYYY-MM-DD')),
           partition p_201305 values less than (TO_DATE('2013-06-01', 'YYYY-MM-DD')),
           partition p_201306 values less than (TO_DATE('2013-07-01', 'YYYY-MM-DD')),
           partition p_201307 values less than (TO_DATE('2013-08-01', 'YYYY-MM-DD')),
           partition p_201308 values less than (TO_DATE('2013-09-01', 'YYYY-MM-DD')),
           partition p_201309 values less than (TO_DATE('2013-10-01', 'YYYY-MM-DD')),
           partition p_201310 values less than (TO_DATE('2013-11-01', 'YYYY-MM-DD')),
           partition p_201311 values less than (TO_DATE('2013-12-01', 'YYYY-MM-DD')),
           partition p_201312 values less than (TO_DATE('2014-01-01', 'YYYY-MM-DD')),
           partition p_201401 values less than (TO_DATE('2014-02-01', 'YYYY-MM-DD')),
           Within last values less p_201402 Partition (the TO_DATE ( '2014-03-01', 'YYYY-the MM-DD')), 
           Partition P_max values less Within last (MAXVALUE) 
           ) 
           ;

ALTER NBR Not Modify Table RANGE_PART_TAB null; 
- The following is inserted 2013 throughout the year and the date of random numbers indicate Fujian number meaning (591-599) of a random number of records, a total of 100,000, as follows: 
INSERT INTO range_part_tab (the above mentioned id, deal_date, area_code, nbr, Contents) 
      the SELECT rownum, 
             to_date (the TO_CHAR ( 365-SYSDATE, 'J') + TRUNC (DBMS_RANDOM.VALUE (0,365)), 'J'), 
             ceil (DBMS_RANDOM.VALUE (591,599)), 
             ceil (DBMS_RANDOM.VALUE (18900000001,18999999999)), 
             RPAD ( '* ', 400,' * ') 
        from Dual 
      Connect by rownum <= 100000; 
the commit;
 
- the following is inserted throughout the year 2014, the random number and the date indicates Fujian area Code meaning (591-599) of a random number of records, a total of 100,000, as follows: 
INSERT INTO range_part_tab (the above mentioned id, deal_date, area_code, nbr, Contents) 
      the SELECT rownum,
             to_date( to_char(sysdate,'J')+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J'),
             ceil(dbms_random.value(591,599)),
             ceil(dbms_random.value(18900000001,18999999999)),
             rpad('*',400,'*')
        from dual
      connect by rownum <= 100000;
commit;

create index idx_part_id on range_part_tab (id) ;
create index idx_part_nbr on range_part_tab (nbr) local;
 
- statistical information systems generally automatic collection, this is the first time after the completion of the table need to operate it, in order to facilitate testing
exec dbms_stats.gather_table_stats(ownname => 'LJB',tabname => 'RANGE_PART_TAB',estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE) ;  
Implementation Plan
the SELECT max (nbr) max_nbr from range_part_tab Partition (p_201305);
the SET LINESIZE 1000

ON AUTOTRACE the SET

------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |     1 |     8 |     2   (0)| 00:00:01 |       |       |
|   1 |  SORT AGGREGATE             |              |     1 |     8 |            |          |       |       |
|   2 |   PARTITION RANGE SINGLE    |              |     1 |     8 |     2   (0)| 00:00:01 |     5 |     5 |
|   3 |    INDEX FULL SCAN (MIN/MAX)| IDX_PART_NBR |     1 |     8 |     2   (0)| 00:00:01 |     5 |     5 |
------------------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          2  consistent gets

select max(nbr) max_nbr
  from range_part_tab
 where deal_date >= TO_DATE('2013-05-01', 'YYYY-MM-DD')
   and deal_date < TO_DATE('2013-06-01', 'YYYY-MM-DD');
执行计划
----------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |                |     1 |    17 |   170   (0)| 00:00:03 |       |       |
|   1 |  SORT AGGREGATE         |                |     1 |    17 |            |          |       |       |
|   2 |   PARTITION RANGE SINGLE|                |    22 |   374 |   170   (0)| 00:00:03 |     5 |     5 |
|   3 |    TABLE ACCESS FULL    | RANGE_PART_TAB |    22 |   374 |   170   (0)| 00:00:03 |     5 |     5 |
----------------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          Block the gets db 0 
        568 consistent the gets 

the SELECT COUNT (*) max_nbr from range_part_tab Partition (p_201305); 
Implementation Plan 
------------------------------------------------------------------------------------------------
| Id  | Operation               | Name         | Rows  | Cost (%CPU)| Time     | Pstart| Pstop |
---------------------------- -------------------------------------------------- ------------------ 
| 0 | the SELECT a STATEMENT | | 1 | 8 (0) | 00:00:01 | | | 
| 1 | SORT AGGREGATE | | 1 | | | | | 
| 2 | the PARTITION the RANGE SINGLE | | 8716 |. 8 (0) | 00:00:01 |. 5 |. 5 | 
|. 3 | the INDEX the FAST SCAN FULL | IDX_PART_NBR | 8716 |. 8 (0) | 00:00:01 | 5 | 5 | 
--------------------------------------------- -------------------------------------------------- - 
statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         29  consistent gets   

select count(*) max_nbr
  from range_part_tab
 where deal_date >= TO_DATE('2013-05-01', 'YYYY-MM-DD')
   and deal_date < TO_DATE('2013-06-01', 'YYYY-MM-DD');
执行计划
----------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------
| 0 | a STATEMENT the SELECT | |. 1 |. 9 | 170. (0) | 00:00:03 | | | 
|   1 |  SORT AGGREGATE         |                |     1 |     9 |            |          |       |       |
|   2 |   PARTITION RANGE SINGLE|                |    22 |   198 |   170   (0)| 00:00:03 |     5 |     5 |
|. 3 | the ACCESS TABLE FULL | RANGE_PART_TAB | 22 is | 198 | 170. (0) | 00:00:03 |. 5 | 5 | 
------------------------------------------------ -------------------------------------------------- -------- 
statistics 
---------------------------------------- ------------------ 
          0 recursive This Calls 
          0 db Block the gets 
        568 consistent the gets 
        
the SELECT SUM (nbr) max_nbr from range_part_tab Partition (p_201305); 
Implementation plan 
------- -------------------------------------------------- -----------------------------------------------
| Id  | Operation               | Name         | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |              |     1 |     8 |     8   (0)| 00:00:01 |       |       |
|   1 |  SORT AGGREGATE         |              |     1 |     8 |            |          |       |       |
|   2 |   PARTITION RANGE SINGLE|              |  8716 | 69728 |     8   (0)| 00:00:01 |     5 |     5 |
|   3 |    INDEX FAST FULL SCAN | IDX_PART_NBR |  8716 | 69728 |     8   (0)| 00:00:01 |     5 |     5 |
--------------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         29  consistent gets
            
select sum(nbr) max_nbr
  from range_part_tab
 where deal_date >= TO_DATE('2013-05-01', 'YYYY-MM-DD')
   and deal_date < TO_DATE('2013-06-01', 'YYYY-MM-DD');
执行计划
----------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |                |     1 |    17 |   170   (0)| 00:00:03 |       |       |
|   1 |  SORT AGGREGATE         |                |     1 |    17 |            |          |       |       |
| 2 | the PARTITION the RANGE SINGLE | | 22 is | 374 | 170. (0) | 00:00:03 |. 5 |. 5 | 
|. 3 | the ACCESS TABLE FULL | RANGE_PART_TAB | 22 is | 374 | 170. (0) | 00:00:03 | 5 | 5 | 
--------------------------------------------- -------------------------------------------------- ----------- 
statistics 
------------------------------------- --------------------- 
          0 recursive This Calls 
          0 db Block the gets 
        568 consistent the gets    
   

the SELECT DISTINCT (nbr) from range_part_tab Partition (p_201305); 
Implementation plan 
----- -------------------------------------------------- -------------------------------------------------
| Id  | Operation               | Name         | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |              |  8660 | 69280 |     9  (12)| 00:00:01 |       |       |
|   1 |  HASH UNIQUE            |              |  8660 | 69280 |     9  (12)| 00:00:01 |       |       |
|   2 |   PARTITION RANGE SINGLE|              |  8716 | 69728 |     8   (0)| 00:00:01 |     5 |     5 |
|   3 |    INDEX FAST FULL SCAN | IDX_PART_NBR |  8716 | 69728 |     8   (0)| 00:00:01 |     5 |     5 |
--------------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         29  consistent gets
          0  physical reads
          0  redo size
     152890  bytes sent via SQL*Net to client
       6741  bytes received via SQL*Net from client
        577  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       8635  rows processed
              
select distinct(nbr)
  from range_part_tab
 where deal_date >= TO_DATE('2013-05-01', 'YYYY-MM-DD')
   and deal_date < TO_DATE('2013-06-01', 'YYYY-MM-DD');
| Id | Operation | the Name | the Rows | Bytes | Cost (% the CPU) | Time | Pstart | Pstop |
------------------------------------------------ -------------------------------------------------- --------
Implementation plan
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |                |    22 |   374 |   171   (1)| 00:00:03 |       |       |
|   1 |  HASH UNIQUE            |                |    22 |   374 |   171   (1)| 00:00:03 |       |       |
|   2 |   PARTITION RANGE SINGLE|                |    22 |   374 |   170   (0)| 00:00:03 |     5 |     5 |
|   3 |    TABLE ACCESS FULL    | RANGE_PART_TAB |    22 |   374 |   170   (0)| 00:00:03 |     5 |     5 |
----------------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        568  consistent gets
          0  physical reads
          0  redo size
     152886  bytes sent via SQL*Net to client
       6741  bytes received via SQL*Net from client
        577  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       8635  rows processed   
   
---<=和<,<=扫描了两个分区
select count(*)
  from range_part_tab
 where deal_date >= TO_DATE('2013-05-01 00:00:00', 'YYYY-MM-DD hh24:mi:ss')
   and deal_date <= TO_DATE('2013-06-01 00:00:00', 'YYYY-MM-DD hh24:mi:ss');
  COUNT(*)
----------
    8635
执行计划
------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT          |                |     1 |     9 |   340   (1)| 00:00:05 |       |       |
|   1 |  SORT AGGREGATE           |                |     1 |     9 |            |          |       |       |
|   2 |   PARTITION RANGE ITERATOR|                |   497 |  4473 |   340   (1)| 00:00:05 |     5 |     6 |
|*  3 |    TABLE ACCESS FULL      | RANGE_PART_TAB |   497 |  4473 |   340   (1)| 00:00:05 |     5 |     6 |
------------------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1136  consistent gets 
                
select count(*)
  from range_part_tab
 where deal_date >= TO_DATE('2013-05-01 00:00:00', 'YYYY-MM-DD hh24:mi:ss')
   and deal_date < TO_DATE('2013-06-01 00:00:00', 'YYYY-MM-DD hh24:mi:ss');      
  COUNT(*)
----------
    8635   
执行计划
----------------------------------------------------------------------------------------------------------
| Id  | Operation               | Name           | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |                |     1 |     9 |   170   (0)| 00:00:03 |       |       |
|   1 |  SORT AGGREGATE         |                |     1 |     9 |            |          |       |       |
|   2 |   PARTITION RANGE SINGLE|                |    22 |   198 |   170   (0)| 00:00:03 |     5 |     5 |
|   3 |    TABLE ACCESS FULL    | RANGE_PART_TAB |    22 |   198 |   170   (0)| 00:00:03 |     5 |     5 |
----------------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        568  consistent gets   

  When are low but partition index performance:

drop table part_tab purge;
create table part_tab (id int,col2 int,col3 int)
        partition by range (id)
        (
        partition p1 values less than (10000),
        partition p2 values less than (20000),
        partition p3 values less than (30000),
        partition p4 values less than (40000),
        partition p5 values less than (50000),
        partition p6 values less than (60000),
        partition p7 values less than (70000),
        partition p8 values less than (80000),
        partition p9 values less than (90000),
        partition p10 values less than (100000),
        partition p11 values less than (maxvalue)
        )
        ;
insert into part_tab select rownum,rownum+1,rownum+2 from dual connect by rownum <=110000;
commit;
create  index idx_par_tab_col2 on part_tab(col2) local;
create  index idx_par_tab_col3 on part_tab(col3) ;

drop table norm_tab purge;
create table norm_tab  (id int,col2 int,col3 int);
insert into norm_tab select rownum,rownum+1,rownum+2 from dual connect by rownum <=110000;
commit;
create  index idx_nor_tab_col2 on norm_tab(col2) ;
create  index idx_nor_tab_col3 on norm_tab(col3) ;

set autotrace traceonly
set linesize 1000
set timing on 
select * from part_tab where col2=8 ;
执行计划
-----------------------------------------------------------------------------------------------------------------------
| Id  | Operation                          | Name             | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                   |                  |     1 |    39 |    13   (0)| 00:00:01 |       |       |
|   1 |  PARTITION RANGE ALL               |                  |     1 |    39 |    13   (0)| 00:00:01 |     1 |    11 |
|   2 |   TABLE ACCESS BY LOCAL INDEX ROWID| PART_TAB         |     1 |    39 |    13   (0)| 00:00:01 |     1 |    11 |
|*  3 |    INDEX RANGE SCAN                | IDX_PAR_TAB_COL2 |     1 |       |    12   (0)| 00:00:01 |     1 |    11 |
-----------------------------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         24  consistent gets
          0  physical reads
          0  redo size
        539  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
          
          
select * from norm_tab where col2=8 ;

执行计划
------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                  |     1 |    39 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| NORM_TAB         |     1 |    39 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_NOR_TAB_COL2 |     1 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
        543  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
        
             
select * from part_tab where col2=8 and id=2;
select * from norm_tab where col2=8 and id=2;

--查看索引高度等信息
select index_name,
          blevel,
          leaf_blocks,
          num_rows,
          distinct_keys,
          clustering_factor
     from user_ind_statistics
    where table_name in( 'NORM_TAB');
    
index_name SELECT, 
          blevel, 
          leaf_blocks, 
          NUM_ROWS, 
          distinct_keys, 
          of clustering_factor the FROM USER_IND_PARTITIONS index_name like WHERE 'IDX_PAR_TAB%'; 
          
height affects performance index ---

  At the same time take the case of minimum and maximum values:

MAX / MIN index optimization 
  drop Table T purge; 
  Create Table T AS SELECT * from dba_objects; 
  Update T SET object_id = rownum; 
  the commit; 
  ALTER Table T the Add constraint pk_object_id Primary Key (the OBJECT_ID); 
  SET AUTOTRACE ON 
  SET LINESIZE 1000 
  SELECT max ( object_id) from T; 
  SELECT min (object_id) from T; 

  
- the equivalence of rewriting, rewriting a small number of complex SQL better performance 
SET LINESIZE 1000 
SET AUTOTRACE ON 

SELECT max (object_id), min (object_id) from T ; 
execution plan 
----------------------------------------------- --------------------------------------- 
| Id | Operation | the Name | the Rows | Bytes | Cost (% CPU) | Time | 
----------- -------------------------------------------------- -------------------------
|   0 | SELECT STATEMENT      |              |     1 |    13 |    46   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE       |              |     1 |    13 |            |          |
|   2 |   INDEX FAST FULL SCAN| PK_OBJECT_ID | 74796 |   949K|    46   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        160  consistent gets
          0  physical reads
          0  redo size
        502  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
   
   
          
select max, min 
  from (select max(object_id) max from t ) a,
       (select min(object_id) min from t ) b;
       
执行计划
---------------------------------------------------------------------------------------------
| Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |              |     1 |    26 |     4   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                |              |     1 |    26 |     4   (0)| 00:00:01 |
| 2 | the VIEW | |. 1 | 13 is | 2 (0) | 00:00:01 | 
|. 3 | AGGREGATE to the SORT | |. 1 | 13 is | | | 
|. 4 | SCAN FULL the INDEX (MIN / MAX) | PK_OBJECT_ID |. 1 | 13 is | 2 (0) | 00:00:01 | 
|. 5 | the VIEW | |. 1 | 13 is | 2 (0) | 00:00:01 | 
|. 6 | AGGREGATE to the SORT | |. 1 | 13 is | | | 
|. 7 | SCAN FULL the INDEX (MIN / MAX) | PK_OBJECT_ID |. 1 | 13 is | 2 (0) | 00:00:01 | 
------------------------ -------------------------------------------------- ------------------- 
statistics 
----------------------------- -----------------------------
          0  recursive calls
          0  db block gets
          4  consistent gets
          0  physical reads
          0  redo size
        480  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

  Consider a single combined index Index Example:

The combination of the index index single prefix is consistent 
drop purge Table T; 
Create Table T AS SELECT * from dba_objects; 
Create index idx_object_id ON T (object_id, object_type); 
SET AUTOTRACE TRACEONLY 
SET LINESIZE 1000 
- the index can be used, because object_id column is the prefix 

select * from t where object_id = 19 ; 
execution plan 
------------------------------------ -------------------------------------------------- ------- 
| Id | Operation | the Name | the Rows | Bytes | Cost (% the CPU) | Time | 
------------------------ -------------------------------------------------- -------------------  
| 0 | the SELECT a STATEMENT | | 1 | 207 | 3 (0) | 00:00:01 |
| 1 | TABLE ACCESS BY INDEX the ROWID | T | 1 | 207 | 3 (0) | 00:00:01 |
| * 2 | INDEX RANGE SCAN | IDX_OBJECT_ID | 1 | | 2 (0) | 00:00:01 | 
-------------------------- -------------------------------------------------- ----------------- 
statistics 
------------------------------- --------------------------- 
          0 recursive This Calls 
          0 db Block the gets 
          4 consistent the gets 
          0 PHYSICAL reads 
          0 redo size 
       1392 bytes Sent Via SQL * Net Client to 
        416 bytes Via the SQL * Net Received from Client 
          2 the SQL * Net roundtrips to / from Client 
prefix single combined index inconsistency index 
drop index idx_object_id;
          0  sorts (memory)
          Sorts 0 (Disk) 
          1 rows Processed 
statistics



ON t index idx_object_id the Create (object_type, object_id); 
- The following can not use the index, because the object_id column is a suffix 

select * from t where object_id = 19 ; 
 execution plan 
-------------- -------------------------------------------------- ---------- 
| Id | Operation | the Name | the Rows | Bytes | Cost (% the CPU) | Time | 
--------------------- -------------------------------------------------- --- 
| 0 | the SELECT a STATEMENT | | 12 | 2484 | 292 (1) | 00:00:04 | 
| * 1 | TABLE ACCESS FULL | T | 12 | 2484 | 292 (1) | 00:00:04 | 
-------------------------------------------------- ------------------------ 
-------------------------- -------------------------------- 
          0 recursive This Calls
          0  db block gets
       1049  consistent gets
          0  physical reads
          0  redo size
       1389  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

  And in combination query optimization related to:

drop table t purge;
create table t as select * from dba_objects;
update t set object_id=rownum ;
create index idx_id_type on t(object_id,object_type);

UPDATE t SET OBJECT_ID=20 WHERE ROWNUM<=26000;
UPDATE t SET OBJECT_ID=21 WHERE OBJECT_ID<>20;
COMMIT;
set linesize 1000
set pagesize 1
alter session set statistics_level=all ;

select  /*+index(t,idx1_object_id)*/ * from t  where object_TYPE='TABLE'  AND OBJECT_ID >= 20 AND OBJECT_ID<= 21;
select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
--------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name           | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                |      1 |        |   2939 |00:00:00.02 |    1117 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T              |      1 |   3411 |   2939 |00:00:00.02 |    1117 |
|*  2 |   INDEX RANGE SCAN          | IDX_ID_TYPE    |      1 |    299 |   2939 |00:00:00.02 |     736 |
--------------------------------------------------------------------------------------------------------
2 - access("OBJECT_ID">=20 AND "OBJECT_TYPE"='TABLE' AND "OBJECT_ID"<=21)
    filter("OBJECT_TYPE"='TABLE')
已选择25行。

select  /*+index(t,idx_id_type)*/ * from t t where object_TYPE='TABLE'  AND  OBJECT_ID IN (20,21);
select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
---------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name           | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                |      1 |        |   2939 |00:00:00.01 |     598 |
|   1 |  INLIST ITERATOR             |                |      1 |        |   2939 |00:00:00.01 |     598 |
|   2 |   TABLE ACCESS BY INDEX ROWID| T              |      2 |   3411 |   2939 |00:00:00.01 |     598 |
| * 3 | INDEX RANGE SCAN | IDX_ID_TYPE | 2 | 1 | 2939 | 00: 00: 00.01 | 217 | 
-------------------------- -------------------------------------------------- ----------------------------- 
. 3 - Access ((( "the OBJECT_ID" = OR 20 is "the OBJECT_ID" = 21 is)) the AND " OBJECT_TYPE "= 'TABLE') 
has selected 25 lines. 

--- col1, col2, col3 index case, and if not given query condition is COL2, COL3 can only play the role of inspection (still in the optimization) 

drop the Table t purge; 
the Create the Table t AS the SELECT * from dba_objects; 
UPDATE T the SET the oBJECT_ID = 20 is the WHERE rOWNUM <= 26000; 
the UPDATE T the SET the oBJECT_ID = 21 is the WHERE the oBJECT_ID <> 20 is; 
the Update T SET object_id = 22 is WHERE rownum <= 10000; 
a COMMIT; 

Create index idx_union ON T (object_type, object_id, owner); 
set autotrace off
set linesize 1000
select * from t where object_type='VIEW' and OWNER='LJB';
select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |      1 |        |      4 |00:00:00.01 |      24 |  19 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T         |      1 |      9 |      4 |00:00:00.01 |      24 |  19 |
|*  2 |   INDEX RANGE SCAN          | IDX_UNION |      1 |     22 |      4 |00:00:00.01 |      21 |  19 |
------------------------------------------------------------------------------------------------------------

select /*+INDEX(T,idx_union)*/ * from t T where object_type='VIEW' and OBJECT_ID IN (20,21,22) AND OWNER='LJB';
----------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |           |      1 |        |      4 |00:00:00.01 |      13 |
|   1 |  INLIST ITERATOR             |           |      1 |        |      4 |00:00:00.01 |      13 |
|   2 |   TABLE ACCESS BY INDEX ROWID| T         |      3 |      1 |      4 |00:00:00.01 |      13 |
|*  3 |    INDEX RANGE SCAN          | IDX_UNION |      3 |      1 |      4 |00:00:00.01 |      10 |
----------------------------------------------------------------------------------------------------

类似
select /*+INDEX(T,idx_union)*/ * from t T where (object_type='VIEW' and OBJECT_ID =20 AND OWNER='LJB')
                                                or (object_type='VIEW' and OBJECT_ID =21 AND OWNER='LJB')
                                                or (object_type='VIEW' and OBJECT_ID =22 AND OWNER='LJB')

  

Guess you like

Origin www.cnblogs.com/sunliyuan/p/12325656.html