Re: Query optimization

From: ddf <oratune_at_msn.com>
Date: Fri, 10 Jan 2014 08:24:45 -0800 (PST)
Message-ID: <01385457-fc08-422e-8bde-e1ee6dd963ab_at_googlegroups.com>


[Quoted] On Friday, January 10, 2014 6:14:23 AM UTC-7, Mark wrote:
> I have a question about index usage in table queries. We need to do
>
> fast queries on new tables. Therefore the standard method of
>
> generating table statistics does not work. We have verified that
>
> Oracle is not using the indexes.
>
>
>
> Assuming that the tables are less than 1 day old and have 1-2Mio
>
> records/hour written to them what is the best way to achieve this?
>
>
>
> An added complication is that the tables are referred to by synonyms
>
> as the user has no way to predict the actual table name.
>
> --
>
> (\__/) M.
>
> (='.'=) If a man stands in a forest and no woman is around
>
> (")_(") is he still wrong?

Let's look at (hopefully) an example similar to the situation you almost described:

SQL>
SQL> --
SQL> -- Create an empty table with no indexes
SQL> --
SQL> create table emp2 as select * from emp where 0=1;

Table created.

SQL>
SQL> --
SQL> -- Create an index on the empty table
SQL> --
SQL> create index empno_idx on emp2(empno);

Index created.

SQL>
SQL> --
SQL> -- Create another index on that same table
SQL> --
SQL> create index sal_idx on emp2(sal);

Index created.

SQL>
SQL> --
SQL> -- Create yet another index on this same table
SQL> --
SQL> create index ename_job_idx on emp2(ename, job);

Index created.

SQL>
SQL> --
SQL> -- Create one more index
SQL> --
SQL> create index mgr_idx on emp2(nvl(mgr,0000));

Index created.

SQL>
SQL> --
SQL> -- Populate the table (will insert 1,800,000 rows)
SQL> --
SQL>
SQL> begin
  2  	     for i in 1..100000 loop
  3  		     insert into emp2
  4  		     select * from emp;
  5  	     end loop;
  6
  7  	     commit;

  8 end;
  9 /

PL/SQL procedure successfully completed.

SQL>
SQL> --
SQL> -- Select from emp2 and see if any indexes are used
SQL> --
SQL> set autotrace on
SQL>
SQL> select *

  2 from emp2
  3 where job = 'CLERK';

     EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
      7876 ADAMS      CLERK           7788 12-JAN-83       1100                    20
      7876 ADAMS      CLERK           7788 12-JAN-83       1100                    20
...
      7900 JAMES      CLERK           7698 03-DEC-81        950                    30
      7934 MILLER     CLERK           7782 23-JAN-82       1300                    10
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20

400000 rows selected.

Execution Plan



Plan hash value: 2941272003

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

| 0 | SELECT STATEMENT | | 413K| 34M| 3029 (1)| 00:00:01 | |* 1 | TABLE ACCESS FULL| EMP2 | 413K| 34M| 3029 (1)| 00:00:01 |

Predicate Information (identified by operation id):


   1 - filter("JOB"='CLERK')

Note


  • dynamic sampling used for this statement (level=2)
  • automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold

Statistics


          6  recursive calls
          2  db block gets
      47465  consistent gets
      10582  physical reads
       4408  redo size
   17793420  bytes sent via SQL*Net to client
     293845  bytes received via SQL*Net from client
      26668  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
     400000  rows processed

SQL>
SQL> select *
  2 from emp2
  3 where nvl(mgr,0000)=0000;

     EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7839 KING       PRESIDENT            17-NOV-81       5000                    10
      7939 DUKE       CEO                  17-NOV-81       5000                    10
      7839 KING       PRESIDENT            17-NOV-81       5000                    10
...
      7939 DUKE       CEO                  17-NOV-81       5000                    10
      7949 PRINCE     CFO                  17-NOV-81       5000                    10
      7959 QUEEN      CIO                  17-NOV-81       5000                    10
      7869 JACK       PRESIDENT            17-NOV-81       5000                    10

500000 rows selected.

Execution Plan



Plan hash value: 1077700836
| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         | 18634 |  1819K|     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP2    | 18634 |  1819K|     1   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | MGR_IDX |  7454 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------

Predicate Information (identified by operation id):


   2 - access(NVL("MGR",0000)=0000)

Note


  • dynamic sampling used for this statement (level=2)
  • automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold

Statistics


          6  recursive calls
          1  db block gets
      88814  consistent gets
       9613  physical reads
     818960  redo size
   15553193  bytes sent via SQL*Net to client
     367182  bytes received via SQL*Net from client
      33335  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
     500000  rows processed

SQL>
SQL> set autotrace off
SQL>
SQL> --
SQL> -- Generate statistics

SQL> --
SQL> exec dbms_stats.gather_table_stats('GRIBNAUT', 'EMP2', estimate_percent=>100, cascade=>true)

PL/SQL procedure successfully completed.

SQL>
SQL> --
SQL> -- Try the queries again
SQL> --
SQL> set autotrace on
SQL>
SQL> select *

  2 from emp2
  3 where job = 'CLERK';

     EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
      7876 ADAMS      CLERK           7788 12-JAN-83       1100                    20
      7900 JAMES      CLERK           7698 03-DEC-81        950                    30
...
      7900 JAMES      CLERK           7698 03-DEC-81        950                    30
      7934 MILLER     CLERK           7782 23-JAN-82       1300                    10
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20

400000 rows selected.

Execution Plan



Plan hash value: 2941272003

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

| 0 | SELECT STATEMENT | | 400K| 14M| 3029 (1)| 00:00:01 | |* 1 | TABLE ACCESS FULL| EMP2 | 400K| 14M| 3029 (1)| 00:00:01 |

Predicate Information (identified by operation id):


   1 - filter("JOB"='CLERK')

Note


  • automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold

Statistics


          0  recursive calls
          1  db block gets
      37029  consistent gets
      10365  physical reads
          0  redo size
   17793420  bytes sent via SQL*Net to client
     293845  bytes received via SQL*Net from client
      26668  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
     400000  rows processed

SQL>
SQL> select *
  2 from emp2
  3 where nvl(mgr,0000)=0000;

     EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO

---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7839 KING       PRESIDENT            17-NOV-81       5000                    10
      7939 DUKE       CEO                  17-NOV-81       5000                    10
      7949 PRINCE     CFO                  17-NOV-81       5000                    10
...
      7939 DUKE       CEO                  17-NOV-81       5000                    10
      7949 PRINCE     CFO                  17-NOV-81       5000                    10
      7959 QUEEN      CIO                  17-NOV-81       5000                    10
      7869 JACK       PRESIDENT            17-NOV-81       5000                    10

500000 rows selected.

Execution Plan



Plan hash value: 2941272003

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

| 0 | SELECT STATEMENT | | 500K| 18M| 3043 (1)| 00:00:01 | |* 1 | TABLE ACCESS FULL| EMP2 | 500K| 18M| 3043 (1)| 00:00:01 |

Predicate Information (identified by operation id):


   1 - filter(NVL("MGR",0000)=0000)

Note


  • automatic DOP: Computed Degree of Parallelism is 1 because of parallel threshold

Statistics


          1  recursive calls
          1  db block gets
      43720  consistent gets
      10365  physical reads
          0  redo size
   15553193  bytes sent via SQL*Net to client
     367182  bytes received via SQL*Net from client
      33335  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
     500000  rows processed

SQL> [Quoted] If Oracle determines that more than 30% of the table data will be returned then the cost of an index access path is far greater than the cost for a table scan which is why the second run used full table scans rather than the indexes. Note that when statistics were NOT gathered dynamic sampling caused Oracle to use the indexes. This example was run using 11.2.0.3; you may be running an older release (a fact you did not present in your original post) so please report which release of Oracle you are using.

[Quoted] [Quoted] Also, please report how you determined that the indexes are not being used; you posted no execution plans to prove your assertion.

David Fitzjarrell Received on Fri Jan 10 2014 - 17:24:45 CET

Original text of this message