SlideShare a Scribd company logo
Five more things about Oracle SQL and PLSQL
Five things about
SQL and PLSQL
That you might not have known
Thomas Kyte
http://asktom.oracle.com/
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Safe Harbor Statement
The following is intended to outline our general product direction. It is intended for
information purposes only, and may not be incorporated into any contract. It is not a
commitment to deliver any material, code, or functionality, and should not be relied upon
in making purchasing decisions. The development, release, and timing of any features or
functionality described for Oracle’s products remains at the sole discretion of Oracle.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
The optimizer is learning from its mistakes
Functions used, without using a Function
PL/SQL warned you
Location, Location, Location
The most underutilized really cool feature (from five years
ago!)
1
2
3
4
5
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
The optimizer is learning from its mistakes
Functions used, without using a Function
PL/SQL warned you
Location, Location, Location
The most underutilized really cool feature (from five years
ago!)
1
2
3
4
5
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
tkyte%ORA12C> select /*+ gather_plan_statistics */ count(*)
2 from cities_state
3 where name = 'New York city'
4 and state = 'New York'
5 /
COUNT(*)
----------
8175132
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
-------------------------------------------------------------
| Id | Operation | Name | E-Rows | A-Rows |
-------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 1 |
| 1 | SORT AGGREGATE | | 1 | 1 |
|* 2 | TABLE ACCESS FULL| CITIES_STATE | 3398 | 8175K|
-------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("NAME"='New York city' AND "STATE"='New York'))
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
tkyte%ORA12C> select /*+ gather_plan_statistics */ count(*)
2 from cities_state
3 where name = 'New York city'
4 and state = 'New York'
5 /
COUNT(*)
----------
8175132
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
-------------------------------------------------------------
| Id | Operation | Name | E-Rows | A-Rows |
-------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 1 |
| 1 | SORT AGGREGATE | | 1 | 1 |
|* 2 | TABLE ACCESS FULL| CITIES_STATE | 8175K| 8175K|
-------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("NAME"='New York city' AND "STATE"='New York'))
Note
-----
- statistics feedback used for this statement
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
tkyte%ORA12C> exec dbms_spd.flush_sql_plan_directive;
PL/SQL procedure successfully completed.
tkyte%ORA12C> select o.object_name, o.subobject_name col_name,
o.object_type, d.type, d.state, d.reason
2 from dba_sql_plan_directives d, dba_sql_plan_dir_objects o
3 where d.directive_id = o.directive_id
4 and o.owner = user
5 order by 1, 2, 3, 4, 5;
OBJECT_NAME COL_NAME OBJECT TYPE STATE REASON
------------ ---------- ------ ---------------- ---------- ------------------------------------
CITIES_STATE NAME COLUMN DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE
CITIES_STATE STATE COLUMN DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE
CITIES_STATE TABLE DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
tkyte%ORA12C> select /*+ gather_plan_statistics */ count(*)
2 from cities_state
3 where name = 'Los Angeles city'
4 and state = 'California'
5 /
COUNT(*)
----------
3792620
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
-------------------------------------------------------------
| Id | Operation | Name | E-Rows | A-Rows |
-------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 1 |
| 1 | SORT AGGREGATE | | 1 | 1 |
|* 2 | TABLE ACCESS FULL| CITIES_STATE | 5196K| 3792K|
-------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("NAME"='Los Angeles city' AND "STATE"='California'))
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- 1 Sql Plan Directive used for this statement
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
tkyte%ORA12C> select column_name, num_distinct, histogram
2 from user_tab_col_statistics
3 where table_name = 'CITIES_STATE';
COLUMN_NAME NUM_DISTINCT HISTOGRAM
----------- ------------ ---------------
NAME 675 NONE
STATE 50 NONE
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
tkyte%ORA12C> exec dbms_stats.gather_table_stats(user,'CITIES_STATE');
PL/SQL procedure successfully completed.
tkyte%ORA12C> select column_name cname, num_distinct, histogram
2 from user_tab_col_statistics
3 where table_name = 'CITIES_STATE';
CNAME NUM_DISTINCT HISTOGRAM
------------------------------ ------------ ---------------
NAME 675 HYBRID
STATE 50 FREQUENCY
SYS_STS652AVX5KJJE5OOY9V6#UOGP 714 HYBRID
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
The optimizer is learning from its mistakes
Functions used, without using a Function
PL/SQL warned you
Location, Location, Location
The most underutilized really cool feature (from five years
ago!)
1
2
3
4
5
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Indexes on Expressions, aka FBI’s
• Available since Oracle 8i
• Index an expression
– Create index I on T(f(x));
• An index used to be used ONLY if the expression that was indexed was
referenced
• Since 11.2.0.2, this has changed…
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> create table t
2 as
3 select *
4 from all_objects;
Table created.
TKYTE@ORA12C> create index t1_idx on t(substr(object_name,1,10));
Index created.
TKYTE@ORA12C> create index t2_idx on t(trunc(created));
Index created.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> select *
2 from t
3 where object_name = '12345678901';
no rows selected
--------------------------------------------------------------
| Id | Operation | Name | Rows |
--------------------------------------------------------------
| 0 | SELECT STATEMENT | | |
|* 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T | 2 |
|* 2 | INDEX RANGE SCAN | T1_IDX | 358 |
--------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_NAME"='12345678901')
2 - access("T"."SYS_NC00019$"='1234567890')
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> select *
2 from t
3 where created = sysdate;
no rows selected
--------------------------------------------------------------
| Id | Operation | Name | Rows |
--------------------------------------------------------------
| 0 | SELECT STATEMENT | | |
|* 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T | 110 |
|* 2 | INDEX RANGE SCAN | T2_IDX | 358 |
--------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("CREATED"=SYSDATE@!)
2 - access("T"."SYS_NC00020$"=TRUNC(SYSDATE@!))
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
The optimizer is learning from its mistakes
Functions used, without using a Function
PL/SQL warned you
Location, Location, Location
The most underutilized really cool feature (from five years
ago!)
1
2
3
4
5
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Warnings
• PL/SQL Compiler has been warning us since 10.1 (2004!)
• Not widely used
• Can be warnings or compile errors
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Warnings
• Severe: code might cause unexpected action or wrong results
• Performance: condition might cause performance issues
• Informational: code as written won’t be wrong or slow – just bad
code
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> alter session set plsql_warnings='enable:severe';
Session altered.
TKYTE@ORA12C> create or replace procedure p
2 as
3 procedure substr
4 is
5 begin
6 null;
7 end;
8 begin
9 null;
10 end;
11 /
SP2-0804: Procedure created with compilation warnings
TKYTE@ORA12C> show errors
Errors for PROCEDURE P:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/1 PLW-05018: unit P omitted optional AUTHID clause; default value
DEFINER used
3/19 PLW-05004: identifier SUBSTR is also declared in STANDARD or is a
SQL builtin
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> alter session set plsql_warnings='enable:performance';
Session altered.
TKYTE@ORA12C> create or replace procedure p
2 as
3 l_string varchar2(5);
4 begin
5 for x in (select * from emp where empno = l_string)
6 loop
7 null;
8 end loop;
9 end;
10 /
SP2-0804: Procedure created with compilation warnings
TKYTE@ORA12C> show errors
Errors for PROCEDURE P:
LINE/COL ERROR
-------- -----------------------------------------------------------------
5/51 PLW-07204: conversion away from column type may result in
sub-optimal query plan
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> alter session set plsql_warnings='enable:informational';
Session altered.
TKYTE@ORA12C> create or replace procedure p
2 as
3 begin
4 if (null is not null)
5 then
6 dbms_output.put_line( 'hello world' );
7 end if;
8 end;
9 /
SP2-0804: Procedure created with compilation warnings
TKYTE@ORA12C> show errors
Errors for PROCEDURE P:
LINE/COL ERROR
-------- -----------------------------------------------------------------
6/17 PLW-06002: Unreachable code
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> alter session set
2 plsql_warnings='enable:all,disable:5018,error:6009,error:7204';
Session altered.
TKYTE@ORA12C> create or replace procedure p
2 as
3 begin
4 dbms_output.put_line( 'hello world' );
5 exception
6 when others
7 then null;
8 end;
9 /
Warning: Procedure created with compilation errors.
TKYTE@ORA12C> show errors
Errors for PROCEDURE P:
LINE/COL ERROR
-------- -----------------------------------------------------------------
6/6 PLS-06009: procedure "P" OTHERS handler does not end in RAISE or
RAISE_APPLICATION_ERROR
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> alter session set Plsql_Warnings = 'enable:all';
Session altered.
TKYTE@ORA12C> create or replace procedure p authid definer
2 as
3 l_date date := to_date( '01-jan-2011', 'dd-mon-yyyy' );
4 l_start number := dbms_utility.get_cpu_time;
5 begin
6 for x in ( select *
7 from big_table
8 where date_string = l_date )
9 loop
10 null;
11 end loop;
12 dbms_output.put_line( 'CPU: ' ||
13 to_char( dbms_utility.get_cpu_time-l_start ) );
14 end;
15 /
SP2-0804: Procedure created with compilation warnings
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
7 from big_table
8 where date_string = l_date )
9 loop
TKYTE@ORA12C> show errors procedure p
Errors for PROCEDURE P:
LINE/COL ERROR
-------- -----------------------------------------------------------------
8/22 PLW-07204: conversion away from column type may result in
sub-optimal query plan
TKYTE@ORA12C> exec p
CPU: 69003
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> create or replace procedure p authid definer
2 as
3 l_date varchar2(15) := '01-jan-2011';
4 l_start number := dbms_utility.get_cpu_time;
5 begin
6 for x in ( select *
7 from big_table
8 where date_string = l_date )
9 loop
10 null;
11 end loop;
12 dbms_output.put_line( 'CPU: ' ||
13 to_char( dbms_utility.get_cpu_time-l_start ) );
14 end;
15 /
Procedure created.
TKYTE@ORA12C> exec p
CPU: 343
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> create table t
2 ( x varchar2(20) constraint t_pk primary key,
3 y varchar2(30)
4 );
Table created.
TKYTE@ORA12C> insert into t
2 select rownum user_id, username
3 from all_users;
39 rows created.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> create or replace procedure p authid current_user
2 as
3 l_rec t%rowtype;
4 l_key number := 5;
5 begin
6 select * into l_rec from t where x = l_key;
7 for x in (select plan_table_output
8 from TABLE( dbms_xplan.display_cursor() ) )
9 loop
10 dbms_output.put_line( x.plan_table_output );
11 end loop;
12 end;
13 /
SP2-0804: Procedure created with compilation warnings
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
5 begin
6 select * into l_rec from t where x = l_key;
7 for x in (select plan_table_output
TKYTE@ORA12C> show errors
Errors for PROCEDURE P:
LINE/COL ERROR
-------- -----------------------------------------------------------------
6/42 PLW-07204: conversion away from column type may result in
sub-optimal query plan
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> exec p
SQL_ID 18796jgha0hwz, child number 0
-------------------------------------
SELECT * FROM T WHERE X = :B1
Plan hash value: 1601196873
---------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
---------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 3 (100)|
|* 1 | TABLE ACCESS FULL| T | 1 | 29 | 3 (0)|
---------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_NUMBER("X")=:B1)
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> create or replace procedure p authid current_user
2 as
3 l_rec t%rowtype;
4 l_key varchar2(5) := '5';
5 begin
6 select * into l_rec from t where x = l_key;
7 for x in (select plan_table_output
8 from TABLE( dbms_xplan.display_cursor() ) )
9 loop
10 dbms_output.put_line( x.plan_table_output );
11 end loop;
12 end;
13 /
Procedure created.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> exec p
SQL_ID 18796jgha0hwz, child number 1
-------------------------------------
SELECT * FROM T WHERE X = :B1
Plan hash value: 1303508680
------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
------------------------------------------------------------
| 0 | SELECT STATEMENT | | | |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 29 |
|* 2 | INDEX UNIQUE SCAN | T_PK | 1 | |
------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("X"=:B1)
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> CREATE TABLE t
2 (
3 dt date,
4 x int,
5 y varchar2(30)
6 )
7 PARTITION BY RANGE (dt)
8 (
9 PARTITION part1 VALUES
LESS THAN(to_date('31-jan-2011', 'dd-mon-yyyy')),
10 PARTITION part2 VALUES
LESS THAN(to_date('28-feb-2011', 'dd-mon-yyyy'))
11 )
12 /
Table created.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> create or replace procedure p authid current_user
2 as
3 l_date timestamp := timestamp'2011-01-15 00:00:00.000';
4 l_count number;
5 begin
6 select count(*) into l_count from t where dt = l_date;
7
8 for x in (select plan_table_output
9 from TABLE( dbms_xplan.display_cursor() ) )
10 loop
11 dbms_output.put_line( '.'||x.plan_table_output );
12 end loop;
13 end;
14 /
SP2-0804: Procedure created with compilation warnings
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
5 begin
6 select count(*) into l_count from t where dt = l_date;
7
TKYTE@ORA12C> show errors
Errors for PROCEDURE P:
LINE/COL ERROR
-------- -----------------------------------------------------------------
6/47 PLW-07204: conversion away from column type may result in
sub-optimal query plan
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> exec p
.SQL_ID 0t5m83d3m67q7, child number 1
.-------------------------------------
.SELECT COUNT(*) FROM T WHERE DT = :B1
.
.Plan hash value: 3225603066
.
.---------------------------------------------------------------------
.| Id | Operation | Name | Rows | Bytes | Pstart| Pstop |
.---------------------------------------------------------------------
.| 0 | SELECT STATEMENT | | | | | |
.| 1 | SORT AGGREGATE | | 1 | 9 | | |
.| 2 | PARTITION RANGE ALL| | 1 | 9 | 1 | 2 |
.|* 3 | TABLE ACCESS FULL | T | 1 | 9 | 1 | 2 |
.---------------------------------------------------------------------
.
.Predicate Information (identified by operation id):
.---------------------------------------------------
.
. 3 - filter(INTERNAL_FUNCTION("DT")=:B1)
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> create or replace procedure p authid current_user
2 as
3 l_date date := to_date( '2011-01-15', 'yyyy-mm-dd' );
4 l_count number;
5 begin
6 select count(*) into l_count from t where dt = l_date;
7
8 for x in (select plan_table_output
9 from TABLE( dbms_xplan.display_cursor() ) )
10 loop
11 dbms_output.put_line( '.'||x.plan_table_output );
12 end loop;
13 end;
14 /
Procedure created.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> exec p
.SQL_ID 0t5m83d3m67q7, child number 2
.-------------------------------------
.SELECT COUNT(*) FROM T WHERE DT = :B1
.
.Plan hash value: 3660200434
.
.------------------------------------------------------------------------
.| Id | Operation | Name | Rows | Bytes | Pstart| Pstop |
.------------------------------------------------------------------------
.| 0 | SELECT STATEMENT | | | | | |
.| 1 | SORT AGGREGATE | | 1 | 9 | | |
.| 2 | PARTITION RANGE SINGLE| | 1 | 9 | KEY | KEY |
.|* 3 | TABLE ACCESS FULL | T | 1 | 9 | KEY | KEY |
.------------------------------------------------------------------------
.
.Predicate Information (identified by operation id):
.---------------------------------------------------
. 3 - filter("DT"=:B1)
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> alter session set Plsql_Warnings = 'error:all';
Session altered.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Warnings
• Can be set at
– The system level ALTER SYSTEM
– The session level ALTER SESSION
– Unit by unit
ALTER PROCEDURE P COMPILE PLSQL_WARNINGS=‘…’ REUSE
SETTINGS;
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
The optimizer is learning from its mistakes
Functions used, without using a Function
PL/SQL warned you
Location, Location, Location
The most underutilized really cool feature (from five years
ago!)
1
2
3
4
5
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
How your data is organized impacts the plan
• Empno, Hiredate and Ename – what is different about the way they arrive?
• An index on Empno or Hiredate would typically be used to retrieve many
more rows from the table then an index on Ename
• There are various techniques we can employ to “cluster” data differently
• Let’s look at the clustering factor first…
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> create table t1
2 as
3 select chr( ascii('A')+mod(rownum,26) ) ||
to_char(rownum, 'fm00000') key,
4 rpad( 'x', 260, 'x') data
5 from all_objects
6 where rownum <= 26*40;
Table created.
TKYTE@ORA12C> alter table t1 modify (key not null);
Table altered.
TKYTE@ORA12C> create index t1_idx on t1(key);
Index created.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> create table t2
2 as
3 select key, data
4 from t1
5 order by key;
Table created.
TKYTE@ORA12C> create index t2_idx on t2(key);
Index created.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> select min(cnt), max(cnt), avg(cnt)
2 from (
3 select bno, count(*) cnt
4 from (
5 select dbms_rowid.rowid_block_number( rowid ) bno
6 from t1 /* or t2! */
7 )
8 group by bno
9 )
10 /
MIN(CNT) MAX(CNT) AVG(CNT)
---------- ---------- ----------
26 26 26
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> select table_name, blocks, num_rows,
to_char(last_analyzed,'dd-mon hh24:mi:ss') la
2 from user_tables
3 where table_name in ('T1','T2')
4 order by 1;
TABLE_NAME BLOCKS NUM_ROWS LA
-------------------- ---------- ---------- ------------------------
T1 45 1040 25-sep 17:34:33
T2 45 1040 25-sep 17:34:33
TKYTE@ORA12C> select table_name, index_name, clustering_factor,
to_char(last_analyzed,'dd-mon hh24:mi:ss') la
2 from user_indexes
3 where table_name in ('T1','T2')
4 order by 1;
TABLE_NAME INDEX_NAME CLUSTERING_FACTOR LA
-------------------- -------------------- ----------------- ----------------
T1 T1_IDX 1040 25-sep 17:34:33
T2 T2_IDX 40 25-sep 17:34:33
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> select /*+ index( t1 t1_idx ) */ count(data)
2 from t1;
COUNT(DATA)
-----------
1040
TKYTE@ORA12C> select /*+ index( t2 t2_idx ) */ count(data)
2 from t2;
COUNT(DATA)
-----------
1040
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
select /*+ index( t1 t1_idx ) */ count(data)
from t1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 1044 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.00 0.00 0 1044 0 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 103
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ----------------------------------------------
1 1 1 SORT AGGREGATE (cr=1044 pr=0 pw=0 time=1920 us
1040 1040 1040 TABLE ACCESS BY INDEX ROWID BATCHED T1 (cr=10
1040 1040 1040 INDEX FULL SCAN T1_IDX (cr=4 pr=0 pw=0 time=
1044-4 = 1040, the clustering factor of T1_IDX
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
select /*+ index( t2 t2_idx ) */ count(data)
from t2
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 44 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.00 0.00 0 44 0 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 103
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ----------------------------------------------
1 1 1 SORT AGGREGATE (cr=44 pr=0 pw=0 time=1004 us)
1040 1040 1040 TABLE ACCESS BY INDEX ROWID BATCHED T2 (cr=44
1040 1040 1040 INDEX FULL SCAN T2_IDX (cr=4 pr=0 pw=0 time=
44-4 = 40, the clustering factor of T2_IDX
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> select count(data)
2 from t1
3 where key between 'A00000' and 'A00250';
COUNT(DATA)
-----------
9
TKYTE@ORA12C> select * from table(dbms_xplan.display_cursor);
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 12 (100)|
| 1 | SORT AGGREGATE | | 1 | 268 | |
| 2 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 9 | 2412 | 12 (0)|
|* 3 | INDEX RANGE SCAN | T1_IDX | 9 | | 2 (0)|
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("KEY">='A00000' AND "KEY"<='A00250')
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> select count(data)
2 from t2
3 where key between 'A00000' and 'A00250';
COUNT(DATA)
-----------
9
TKYTE@ORA12C> select * from table(dbms_xplan.display_cursor);
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 3 (100)|
| 1 | SORT AGGREGATE | | 1 | 268 | |
| 2 | TABLE ACCESS BY INDEX ROWID BATCHED| T2 | 9 | 2412 | 3 (0)|
|* 3 | INDEX RANGE SCAN | T2_IDX | 9 | | 2 (0)|
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("KEY">='A00000' AND "KEY"<='A00250')
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> select count(data)
2 from t1
3 where key between 'A00000' and 'A00500';
COUNT(DATA)
-----------
19
TKYTE@ORA12C> select * from table(dbms_xplan.display_cursor);
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 14 (100)| |
| 1 | SORT AGGREGATE | | 1 | 268 | | |
|* 2 | TABLE ACCESS FULL| T1 | 20 | 5360 | 14 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("KEY"<='A00500' AND "KEY">='A00000'))
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> select count(data)
2 from t2
3 where key between 'A00000' and 'A00500';
COUNT(DATA)
-----------
19
TKYTE@ORA12C> select * from table(dbms_xplan.display_cursor);
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 3 (100)|
| 1 | SORT AGGREGATE | | 1 | 268 | |
| 2 | TABLE ACCESS BY INDEX ROWID BATCHED| T2 | 20 | 5360 | 3 (0)|
|* 3 | INDEX RANGE SCAN | T2_IDX | 20 | | 2 (0)|
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("KEY">='A00000' AND "KEY"<='A00500')
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> begin
2 dbms_stats.set_table_prefs
3 ( ownname => user,
4 tabname => 'T1',
5 pname => 'TABLE_CACHED_BLOCKS',
6 pvalue => 42 );
7 dbms_stats.set_table_prefs
8 ( ownname => user,
9 tabname => 'T2',
10 pname => 'TABLE_CACHED_BLOCKS',
11 pvalue => 42 );
12
13 dbms_stats.gather_index_stats( user, 'T1_IDX' );
14 dbms_stats.gather_index_stats( user, 'T2_IDX' );
15 end;
16 /
PL/SQL procedure successfully completed.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE@ORA12C> select table_name, index_name, clustering_factor,
to_char(last_analyzed,'dd-mon hh24:mi:ss') la
2 from user_indexes
3 where table_name in ('T1','T2')
4 order by 1;
TABLE_NAME INDEX_NAME CLUSTERING_FACTOR LA
-------------------- -------------------- ----------------- ---------------
T1 T1_IDX 40 25-sep 17:34:36
T2 T2_IDX 40 25-sep 17:34:36
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
The optimizer is learning from its mistakes
Functions used, without using a Function
PL/SQL warned you
Location, Location, Location
The most underutilized really cool feature (from five years
ago!)
1
2
3
4
5
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Quick Story…
I’m going to write a PL/SQL parser…
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE%ORA12C> create user demo
2 identified by demo;
User created.
TKYTE%ORA12C> grant create session,
2 create procedure
3 to demo;
Grant succeeded.
TKYTE%ORA12C> create edition version2
2 as child of ora$base;
Edition created.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE%ORA12C> connect demo/demo
Connected.
DEMO%ORA12C> create or replace
2 procedure my_procedure
3 as
4 begin
5 dbms_output.put_line( 'I am buggy version 1.0' );
6 end;
7 /
Procedure created.
DEMO%ORA12C> create or replace
2 procedure my_procedure2
3 as
4 begin
5 my_procedure;
6 end;
7 /
Procedure created.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
DEMO%ORA12C> exec my_procedure2
I am buggy version 1.0
PL/SQL procedure successfully completed.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
DEMO%ORA12C> alter session
2 set edition = version2;
ERROR:
ORA-38802: edition does not exist
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
DEMO%ORA12C> connect tkyte/tkyte
Connected.
TKYTE%ORA12C> alter user demo
2 enable editions;
User altered.
TKYTE%ORA12C> grant use
2 on edition version2
3 to demo;
Grant succeeded.
TKYTE%ORA12C> grant use
2 on edition version2
3 to scott;
Grant succeeded.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
TKYTE%ORA12C> connect demo/demo
Connected.
DEMO%ORA12C> alter session
2 set edition = version2;
Session altered.
DEMO%ORA12C> select object_name, object_type, status, edition_name
2 from user_objects;
OBJECT_NAME OBJECT_TYPE STATUS EDITION_NAME
------------------------------ ----------- ------ ------------
MY_PROCEDURE PROCEDURE VALID ORA$BASE
MY_PROCEDURE2 PROCEDURE VALID ORA$BASE
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
DEMO%ORA12C> create or replace
2 procedure my_procedure
3 as
4 begin
5 dbms_output.put_line( 'I am fixed in version 2.0' );
6 end;
7 /
Procedure created.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
DEMO%ORA12C> select object_name, edition_name
2 from user_objects;
OBJECT_NAME EDITION_NAME
------------------------------ ------------
MY_PROCEDURE2 ORA$BASE
MY_PROCEDURE VERSION2
DEMO%ORA12C> select object_name, edition_name
2 from user_objects_AE;
OBJECT_NAME EDITION_NAME
------------------------------ ------------
MY_PROCEDURE ORA$BASE
MY_PROCEDURE2 ORA$BASE
MY_PROCEDURE VERSION2
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
DEMO%ORA12C> grant execute on my_procedure2 to scott;
Grant succeeded.
DEMO%ORA12C> select object_name, edition_name from user_objects;
OBJECT_NAME EDITION_NAME
------------------------------ ------------
MY_PROCEDURE2 VERSION2
MY_PROCEDURE VERSION2
DEMO%ORA12C> select object_name, edition_name from user_objects_AE;
OBJECT_NAME EDITION_NAME
------------------------------ ------------
MY_PROCEDURE2 ORA$BASE
MY_PROCEDURE ORA$BASE
MY_PROCEDURE2 VERSION2
MY_PROCEDURE VERSION2
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
DEMO%ORA12C> SELECT SYS_CONTEXT ('userenv', 'current_edition_name') sc
2 FROM DUAL;
SC
---------------
VERSION2
DEMO%ORA12C> exec my_procedure2
I am fixed in version 2.0
PL/SQL procedure successfully completed.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
DEMO%ORA12C> connect demo/demo
Connected.
DEMO%ORA12C> SELECT SYS_CONTEXT ('userenv', 'current_edition_name') sc
2 FROM DUAL;
SC
---------------
ORA$BASE
DEMO%ORA12C> exec my_procedure2
I am buggy version 1.0
PL/SQL procedure successfully completed.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
DEMO%ORA12C> alter session set edition = version2;
Session altered.
DEMO%ORA12C> SELECT SYS_CONTEXT ('userenv', 'current_edition_name') sc
2 FROM DUAL;
SC
---------------
VERSION2
DEMO%ORA12C> exec my_procedure2
I am fixed in version 2.0
PL/SQL procedure successfully completed.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
DEMO%ORA12C> connect scott/tiger
Connected.
SCOTT%ORA12C> SELECT SYS_CONTEXT ('userenv', 'current_edition_name') sc
2 FROM DUAL;
SC
---------------
ORA$BASE
SCOTT%ORA12C> exec demo.my_procedure2
BEGIN demo.my_procedure2; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'DEMO.MY_PROCEDURE2' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
SCOTT%ORA12C> alter session
2 set edition = version2;
Session altered.
SCOTT%ORA12C> exec demo.my_procedure2
I am fixed in version 2.0
PL/SQL procedure successfully completed.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
The optimizer is learning from its mistakes
Functions used, without using a Function
PL/SQL warned you
Location, Location, Location
The most underutilized really cool feature (from five years
ago!)
1
2
3
4
5
Five more things about Oracle SQL and PLSQL

More Related Content

PDF
Oracle ORAchk & EXAchk, What's New in 12.1.0.2.7
PDF
Getting optimal performance from oracle e business suite(aioug aug2015)
PPT
Do You Know The 11g Plan?
PDF
Whats new in oracle ORAchk & EXAchk 18.3.0
PPTX
MySQL Optimizer Overview
PPTX
Melbourne Groundbreakers Tour - Upgrading without risk
PPTX
Sangam 18 - The New Optimizer in Oracle 12c
PPTX
The Five Best Things To Happen To SQL
Oracle ORAchk & EXAchk, What's New in 12.1.0.2.7
Getting optimal performance from oracle e business suite(aioug aug2015)
Do You Know The 11g Plan?
Whats new in oracle ORAchk & EXAchk 18.3.0
MySQL Optimizer Overview
Melbourne Groundbreakers Tour - Upgrading without risk
Sangam 18 - The New Optimizer in Oracle 12c
The Five Best Things To Happen To SQL

Similar to Five more things about Oracle SQL and PLSQL (20)

PPTX
Wellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
PDF
OG Yatra - upgrading to the new 12c+ optimizer
PPTX
How to tune a query - ODTUG 2012
PPTX
Sql and PL/SQL Best Practices I
PPTX
5 Cool Things About SQL
PPTX
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
PDF
Managing Statistics for Optimal Query Performance
PPTX
PPTX
A few things about the Oracle optimizer - 2013
PPT
Dbms plan - A swiss army knife for performance engineers
PDF
Find it. Fix it. Real-World SQL Tuning Cases with Karen Morton
ODP
Performance tuning
PPTX
OpenWorld 2018 - 20 years of hints and tips
PPTX
More than 12 More things about Oracle Database 12c
PPTX
Five_Things_You_Might_Not_Know_About_Oracle_Database_v2.pptx
PPTX
Embarcadero In Search of Plan Stability Part 1 Webinar Slides
PPTX
PLSQL Advanced
PPTX
Oracle Query Optimizer - An Introduction
PPT
Oracle SQL, PL/SQL best practices
PPTX
Melbourne Groundbreakers Tour - Hints and Tips
Wellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
OG Yatra - upgrading to the new 12c+ optimizer
How to tune a query - ODTUG 2012
Sql and PL/SQL Best Practices I
5 Cool Things About SQL
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Managing Statistics for Optimal Query Performance
A few things about the Oracle optimizer - 2013
Dbms plan - A swiss army knife for performance engineers
Find it. Fix it. Real-World SQL Tuning Cases with Karen Morton
Performance tuning
OpenWorld 2018 - 20 years of hints and tips
More than 12 More things about Oracle Database 12c
Five_Things_You_Might_Not_Know_About_Oracle_Database_v2.pptx
Embarcadero In Search of Plan Stability Part 1 Webinar Slides
PLSQL Advanced
Oracle Query Optimizer - An Introduction
Oracle SQL, PL/SQL best practices
Melbourne Groundbreakers Tour - Hints and Tips
Ad

More from Connor McDonald (20)

PDF
Flashback ITOUG
PDF
Sangam 19 - PLSQL still the coolest
PDF
Sangam 19 - Analytic SQL
PDF
UKOUG - 25 years of hints and tips
PDF
Sangam 19 - Successful Applications on Autonomous
PDF
Sangam 2019 - The Latest Features
PDF
UKOUG 2019 - SQL features
PDF
APEX tour 2019 - successful development with autonomous
PDF
APAC Groundbreakers 2019 - Perth/Melbourne
PDF
OOW19 - Flashback, not just for DBAs
PDF
OOW19 - Read consistency
PDF
OOW19 - Slower and less secure applications
PDF
OOW19 - Killing database sessions
PDF
OOW19 - Ten Amazing SQL features
PDF
Latin America Tour 2019 - 18c and 19c featues
PDF
Latin America tour 2019 - Flashback
PDF
Latin America Tour 2019 - 10 great sql features
PDF
Latin America Tour 2019 - pattern matching
PDF
Latin America Tour 2019 - slow data and sql processing
PDF
ANSI vs Oracle language
Flashback ITOUG
Sangam 19 - PLSQL still the coolest
Sangam 19 - Analytic SQL
UKOUG - 25 years of hints and tips
Sangam 19 - Successful Applications on Autonomous
Sangam 2019 - The Latest Features
UKOUG 2019 - SQL features
APEX tour 2019 - successful development with autonomous
APAC Groundbreakers 2019 - Perth/Melbourne
OOW19 - Flashback, not just for DBAs
OOW19 - Read consistency
OOW19 - Slower and less secure applications
OOW19 - Killing database sessions
OOW19 - Ten Amazing SQL features
Latin America Tour 2019 - 18c and 19c featues
Latin America tour 2019 - Flashback
Latin America Tour 2019 - 10 great sql features
Latin America Tour 2019 - pattern matching
Latin America Tour 2019 - slow data and sql processing
ANSI vs Oracle language
Ad

Recently uploaded (20)

PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Network Security Unit 5.pdf for BCA BBA.
PPT
Teaching material agriculture food technology
PDF
Empathic Computing: Creating Shared Understanding
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Electronic commerce courselecture one. Pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PPTX
Cloud computing and distributed systems.
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Machine learning based COVID-19 study performance prediction
Building Integrated photovoltaic BIPV_UPV.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
Network Security Unit 5.pdf for BCA BBA.
Teaching material agriculture food technology
Empathic Computing: Creating Shared Understanding
Chapter 3 Spatial Domain Image Processing.pdf
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Spectral efficient network and resource selection model in 5G networks
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Electronic commerce courselecture one. Pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Reach Out and Touch Someone: Haptics and Empathic Computing
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Programs and apps: productivity, graphics, security and other tools
MYSQL Presentation for SQL database connectivity
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Cloud computing and distributed systems.
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Machine learning based COVID-19 study performance prediction

Five more things about Oracle SQL and PLSQL

  • 2. Five things about SQL and PLSQL That you might not have known Thomas Kyte http://asktom.oracle.com/ Copyright © 2014, Oracle and/or its affiliates. All rights reserved. |
  • 3. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Safe Harbor Statement The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.
  • 4. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Program Agenda The optimizer is learning from its mistakes Functions used, without using a Function PL/SQL warned you Location, Location, Location The most underutilized really cool feature (from five years ago!) 1 2 3 4 5
  • 5. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Program Agenda The optimizer is learning from its mistakes Functions used, without using a Function PL/SQL warned you Location, Location, Location The most underutilized really cool feature (from five years ago!) 1 2 3 4 5
  • 6. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | tkyte%ORA12C> select /*+ gather_plan_statistics */ count(*) 2 from cities_state 3 where name = 'New York city' 4 and state = 'New York' 5 / COUNT(*) ---------- 8175132
  • 7. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | ------------------------------------------------------------- | Id | Operation | Name | E-Rows | A-Rows | ------------------------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | | 1 | SORT AGGREGATE | | 1 | 1 | |* 2 | TABLE ACCESS FULL| CITIES_STATE | 3398 | 8175K| ------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(("NAME"='New York city' AND "STATE"='New York'))
  • 8. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | tkyte%ORA12C> select /*+ gather_plan_statistics */ count(*) 2 from cities_state 3 where name = 'New York city' 4 and state = 'New York' 5 / COUNT(*) ---------- 8175132
  • 9. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | ------------------------------------------------------------- | Id | Operation | Name | E-Rows | A-Rows | ------------------------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | | 1 | SORT AGGREGATE | | 1 | 1 | |* 2 | TABLE ACCESS FULL| CITIES_STATE | 8175K| 8175K| ------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(("NAME"='New York city' AND "STATE"='New York')) Note ----- - statistics feedback used for this statement
  • 10. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | tkyte%ORA12C> exec dbms_spd.flush_sql_plan_directive; PL/SQL procedure successfully completed. tkyte%ORA12C> select o.object_name, o.subobject_name col_name, o.object_type, d.type, d.state, d.reason 2 from dba_sql_plan_directives d, dba_sql_plan_dir_objects o 3 where d.directive_id = o.directive_id 4 and o.owner = user 5 order by 1, 2, 3, 4, 5; OBJECT_NAME COL_NAME OBJECT TYPE STATE REASON ------------ ---------- ------ ---------------- ---------- ------------------------------------ CITIES_STATE NAME COLUMN DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE CITIES_STATE STATE COLUMN DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE CITIES_STATE TABLE DYNAMIC_SAMPLING USABLE SINGLE TABLE CARDINALITY MISESTIMATE
  • 11. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | tkyte%ORA12C> select /*+ gather_plan_statistics */ count(*) 2 from cities_state 3 where name = 'Los Angeles city' 4 and state = 'California' 5 / COUNT(*) ---------- 3792620
  • 12. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | ------------------------------------------------------------- | Id | Operation | Name | E-Rows | A-Rows | ------------------------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | | 1 | SORT AGGREGATE | | 1 | 1 | |* 2 | TABLE ACCESS FULL| CITIES_STATE | 5196K| 3792K| ------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(("NAME"='Los Angeles city' AND "STATE"='California')) Note ----- - dynamic statistics used: dynamic sampling (level=2) - 1 Sql Plan Directive used for this statement
  • 13. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | tkyte%ORA12C> select column_name, num_distinct, histogram 2 from user_tab_col_statistics 3 where table_name = 'CITIES_STATE'; COLUMN_NAME NUM_DISTINCT HISTOGRAM ----------- ------------ --------------- NAME 675 NONE STATE 50 NONE
  • 14. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | tkyte%ORA12C> exec dbms_stats.gather_table_stats(user,'CITIES_STATE'); PL/SQL procedure successfully completed. tkyte%ORA12C> select column_name cname, num_distinct, histogram 2 from user_tab_col_statistics 3 where table_name = 'CITIES_STATE'; CNAME NUM_DISTINCT HISTOGRAM ------------------------------ ------------ --------------- NAME 675 HYBRID STATE 50 FREQUENCY SYS_STS652AVX5KJJE5OOY9V6#UOGP 714 HYBRID
  • 15. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Program Agenda The optimizer is learning from its mistakes Functions used, without using a Function PL/SQL warned you Location, Location, Location The most underutilized really cool feature (from five years ago!) 1 2 3 4 5
  • 16. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Indexes on Expressions, aka FBI’s • Available since Oracle 8i • Index an expression – Create index I on T(f(x)); • An index used to be used ONLY if the expression that was indexed was referenced • Since 11.2.0.2, this has changed…
  • 17. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> create table t 2 as 3 select * 4 from all_objects; Table created. TKYTE@ORA12C> create index t1_idx on t(substr(object_name,1,10)); Index created. TKYTE@ORA12C> create index t2_idx on t(trunc(created)); Index created.
  • 18. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> select * 2 from t 3 where object_name = '12345678901'; no rows selected -------------------------------------------------------------- | Id | Operation | Name | Rows | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | | |* 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T | 2 | |* 2 | INDEX RANGE SCAN | T1_IDX | 358 | -------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("OBJECT_NAME"='12345678901') 2 - access("T"."SYS_NC00019$"='1234567890')
  • 19. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> select * 2 from t 3 where created = sysdate; no rows selected -------------------------------------------------------------- | Id | Operation | Name | Rows | -------------------------------------------------------------- | 0 | SELECT STATEMENT | | | |* 1 | TABLE ACCESS BY INDEX ROWID BATCHED| T | 110 | |* 2 | INDEX RANGE SCAN | T2_IDX | 358 | -------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("CREATED"=SYSDATE@!) 2 - access("T"."SYS_NC00020$"=TRUNC(SYSDATE@!))
  • 20. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Program Agenda The optimizer is learning from its mistakes Functions used, without using a Function PL/SQL warned you Location, Location, Location The most underutilized really cool feature (from five years ago!) 1 2 3 4 5
  • 21. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Warnings • PL/SQL Compiler has been warning us since 10.1 (2004!) • Not widely used • Can be warnings or compile errors
  • 22. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Warnings • Severe: code might cause unexpected action or wrong results • Performance: condition might cause performance issues • Informational: code as written won’t be wrong or slow – just bad code
  • 23. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> alter session set plsql_warnings='enable:severe'; Session altered. TKYTE@ORA12C> create or replace procedure p 2 as 3 procedure substr 4 is 5 begin 6 null; 7 end; 8 begin 9 null; 10 end; 11 / SP2-0804: Procedure created with compilation warnings TKYTE@ORA12C> show errors Errors for PROCEDURE P: LINE/COL ERROR -------- ----------------------------------------------------------------- 1/1 PLW-05018: unit P omitted optional AUTHID clause; default value DEFINER used 3/19 PLW-05004: identifier SUBSTR is also declared in STANDARD or is a SQL builtin
  • 24. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> alter session set plsql_warnings='enable:performance'; Session altered. TKYTE@ORA12C> create or replace procedure p 2 as 3 l_string varchar2(5); 4 begin 5 for x in (select * from emp where empno = l_string) 6 loop 7 null; 8 end loop; 9 end; 10 / SP2-0804: Procedure created with compilation warnings TKYTE@ORA12C> show errors Errors for PROCEDURE P: LINE/COL ERROR -------- ----------------------------------------------------------------- 5/51 PLW-07204: conversion away from column type may result in sub-optimal query plan
  • 25. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> alter session set plsql_warnings='enable:informational'; Session altered. TKYTE@ORA12C> create or replace procedure p 2 as 3 begin 4 if (null is not null) 5 then 6 dbms_output.put_line( 'hello world' ); 7 end if; 8 end; 9 / SP2-0804: Procedure created with compilation warnings TKYTE@ORA12C> show errors Errors for PROCEDURE P: LINE/COL ERROR -------- ----------------------------------------------------------------- 6/17 PLW-06002: Unreachable code
  • 26. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> alter session set 2 plsql_warnings='enable:all,disable:5018,error:6009,error:7204'; Session altered. TKYTE@ORA12C> create or replace procedure p 2 as 3 begin 4 dbms_output.put_line( 'hello world' ); 5 exception 6 when others 7 then null; 8 end; 9 / Warning: Procedure created with compilation errors. TKYTE@ORA12C> show errors Errors for PROCEDURE P: LINE/COL ERROR -------- ----------------------------------------------------------------- 6/6 PLS-06009: procedure "P" OTHERS handler does not end in RAISE or RAISE_APPLICATION_ERROR
  • 27. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> alter session set Plsql_Warnings = 'enable:all'; Session altered. TKYTE@ORA12C> create or replace procedure p authid definer 2 as 3 l_date date := to_date( '01-jan-2011', 'dd-mon-yyyy' ); 4 l_start number := dbms_utility.get_cpu_time; 5 begin 6 for x in ( select * 7 from big_table 8 where date_string = l_date ) 9 loop 10 null; 11 end loop; 12 dbms_output.put_line( 'CPU: ' || 13 to_char( dbms_utility.get_cpu_time-l_start ) ); 14 end; 15 / SP2-0804: Procedure created with compilation warnings
  • 28. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | 7 from big_table 8 where date_string = l_date ) 9 loop TKYTE@ORA12C> show errors procedure p Errors for PROCEDURE P: LINE/COL ERROR -------- ----------------------------------------------------------------- 8/22 PLW-07204: conversion away from column type may result in sub-optimal query plan TKYTE@ORA12C> exec p CPU: 69003
  • 29. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> create or replace procedure p authid definer 2 as 3 l_date varchar2(15) := '01-jan-2011'; 4 l_start number := dbms_utility.get_cpu_time; 5 begin 6 for x in ( select * 7 from big_table 8 where date_string = l_date ) 9 loop 10 null; 11 end loop; 12 dbms_output.put_line( 'CPU: ' || 13 to_char( dbms_utility.get_cpu_time-l_start ) ); 14 end; 15 / Procedure created. TKYTE@ORA12C> exec p CPU: 343
  • 30. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> create table t 2 ( x varchar2(20) constraint t_pk primary key, 3 y varchar2(30) 4 ); Table created. TKYTE@ORA12C> insert into t 2 select rownum user_id, username 3 from all_users; 39 rows created.
  • 31. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> create or replace procedure p authid current_user 2 as 3 l_rec t%rowtype; 4 l_key number := 5; 5 begin 6 select * into l_rec from t where x = l_key; 7 for x in (select plan_table_output 8 from TABLE( dbms_xplan.display_cursor() ) ) 9 loop 10 dbms_output.put_line( x.plan_table_output ); 11 end loop; 12 end; 13 / SP2-0804: Procedure created with compilation warnings
  • 32. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | 5 begin 6 select * into l_rec from t where x = l_key; 7 for x in (select plan_table_output TKYTE@ORA12C> show errors Errors for PROCEDURE P: LINE/COL ERROR -------- ----------------------------------------------------------------- 6/42 PLW-07204: conversion away from column type may result in sub-optimal query plan
  • 33. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> exec p SQL_ID 18796jgha0hwz, child number 0 ------------------------------------- SELECT * FROM T WHERE X = :B1 Plan hash value: 1601196873 --------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| --------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 3 (100)| |* 1 | TABLE ACCESS FULL| T | 1 | 29 | 3 (0)| --------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(TO_NUMBER("X")=:B1)
  • 34. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> create or replace procedure p authid current_user 2 as 3 l_rec t%rowtype; 4 l_key varchar2(5) := '5'; 5 begin 6 select * into l_rec from t where x = l_key; 7 for x in (select plan_table_output 8 from TABLE( dbms_xplan.display_cursor() ) ) 9 loop 10 dbms_output.put_line( x.plan_table_output ); 11 end loop; 12 end; 13 / Procedure created.
  • 35. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> exec p SQL_ID 18796jgha0hwz, child number 1 ------------------------------------- SELECT * FROM T WHERE X = :B1 Plan hash value: 1303508680 ------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | ------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | | 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 29 | |* 2 | INDEX UNIQUE SCAN | T_PK | 1 | | ------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("X"=:B1)
  • 36. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> CREATE TABLE t 2 ( 3 dt date, 4 x int, 5 y varchar2(30) 6 ) 7 PARTITION BY RANGE (dt) 8 ( 9 PARTITION part1 VALUES LESS THAN(to_date('31-jan-2011', 'dd-mon-yyyy')), 10 PARTITION part2 VALUES LESS THAN(to_date('28-feb-2011', 'dd-mon-yyyy')) 11 ) 12 / Table created.
  • 37. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> create or replace procedure p authid current_user 2 as 3 l_date timestamp := timestamp'2011-01-15 00:00:00.000'; 4 l_count number; 5 begin 6 select count(*) into l_count from t where dt = l_date; 7 8 for x in (select plan_table_output 9 from TABLE( dbms_xplan.display_cursor() ) ) 10 loop 11 dbms_output.put_line( '.'||x.plan_table_output ); 12 end loop; 13 end; 14 / SP2-0804: Procedure created with compilation warnings
  • 38. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | 5 begin 6 select count(*) into l_count from t where dt = l_date; 7 TKYTE@ORA12C> show errors Errors for PROCEDURE P: LINE/COL ERROR -------- ----------------------------------------------------------------- 6/47 PLW-07204: conversion away from column type may result in sub-optimal query plan
  • 39. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> exec p .SQL_ID 0t5m83d3m67q7, child number 1 .------------------------------------- .SELECT COUNT(*) FROM T WHERE DT = :B1 . .Plan hash value: 3225603066 . .--------------------------------------------------------------------- .| Id | Operation | Name | Rows | Bytes | Pstart| Pstop | .--------------------------------------------------------------------- .| 0 | SELECT STATEMENT | | | | | | .| 1 | SORT AGGREGATE | | 1 | 9 | | | .| 2 | PARTITION RANGE ALL| | 1 | 9 | 1 | 2 | .|* 3 | TABLE ACCESS FULL | T | 1 | 9 | 1 | 2 | .--------------------------------------------------------------------- . .Predicate Information (identified by operation id): .--------------------------------------------------- . . 3 - filter(INTERNAL_FUNCTION("DT")=:B1)
  • 40. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> create or replace procedure p authid current_user 2 as 3 l_date date := to_date( '2011-01-15', 'yyyy-mm-dd' ); 4 l_count number; 5 begin 6 select count(*) into l_count from t where dt = l_date; 7 8 for x in (select plan_table_output 9 from TABLE( dbms_xplan.display_cursor() ) ) 10 loop 11 dbms_output.put_line( '.'||x.plan_table_output ); 12 end loop; 13 end; 14 / Procedure created.
  • 41. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> exec p .SQL_ID 0t5m83d3m67q7, child number 2 .------------------------------------- .SELECT COUNT(*) FROM T WHERE DT = :B1 . .Plan hash value: 3660200434 . .------------------------------------------------------------------------ .| Id | Operation | Name | Rows | Bytes | Pstart| Pstop | .------------------------------------------------------------------------ .| 0 | SELECT STATEMENT | | | | | | .| 1 | SORT AGGREGATE | | 1 | 9 | | | .| 2 | PARTITION RANGE SINGLE| | 1 | 9 | KEY | KEY | .|* 3 | TABLE ACCESS FULL | T | 1 | 9 | KEY | KEY | .------------------------------------------------------------------------ . .Predicate Information (identified by operation id): .--------------------------------------------------- . 3 - filter("DT"=:B1)
  • 42. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> alter session set Plsql_Warnings = 'error:all'; Session altered.
  • 43. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Warnings • Can be set at – The system level ALTER SYSTEM – The session level ALTER SESSION – Unit by unit ALTER PROCEDURE P COMPILE PLSQL_WARNINGS=‘…’ REUSE SETTINGS;
  • 44. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Program Agenda The optimizer is learning from its mistakes Functions used, without using a Function PL/SQL warned you Location, Location, Location The most underutilized really cool feature (from five years ago!) 1 2 3 4 5
  • 45. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | How your data is organized impacts the plan • Empno, Hiredate and Ename – what is different about the way they arrive? • An index on Empno or Hiredate would typically be used to retrieve many more rows from the table then an index on Ename • There are various techniques we can employ to “cluster” data differently • Let’s look at the clustering factor first…
  • 46. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> create table t1 2 as 3 select chr( ascii('A')+mod(rownum,26) ) || to_char(rownum, 'fm00000') key, 4 rpad( 'x', 260, 'x') data 5 from all_objects 6 where rownum <= 26*40; Table created. TKYTE@ORA12C> alter table t1 modify (key not null); Table altered. TKYTE@ORA12C> create index t1_idx on t1(key); Index created.
  • 47. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> create table t2 2 as 3 select key, data 4 from t1 5 order by key; Table created. TKYTE@ORA12C> create index t2_idx on t2(key); Index created.
  • 48. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> select min(cnt), max(cnt), avg(cnt) 2 from ( 3 select bno, count(*) cnt 4 from ( 5 select dbms_rowid.rowid_block_number( rowid ) bno 6 from t1 /* or t2! */ 7 ) 8 group by bno 9 ) 10 / MIN(CNT) MAX(CNT) AVG(CNT) ---------- ---------- ---------- 26 26 26
  • 49. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> select table_name, blocks, num_rows, to_char(last_analyzed,'dd-mon hh24:mi:ss') la 2 from user_tables 3 where table_name in ('T1','T2') 4 order by 1; TABLE_NAME BLOCKS NUM_ROWS LA -------------------- ---------- ---------- ------------------------ T1 45 1040 25-sep 17:34:33 T2 45 1040 25-sep 17:34:33 TKYTE@ORA12C> select table_name, index_name, clustering_factor, to_char(last_analyzed,'dd-mon hh24:mi:ss') la 2 from user_indexes 3 where table_name in ('T1','T2') 4 order by 1; TABLE_NAME INDEX_NAME CLUSTERING_FACTOR LA -------------------- -------------------- ----------------- ---------------- T1 T1_IDX 1040 25-sep 17:34:33 T2 T2_IDX 40 25-sep 17:34:33
  • 50. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> select /*+ index( t1 t1_idx ) */ count(data) 2 from t1; COUNT(DATA) ----------- 1040 TKYTE@ORA12C> select /*+ index( t2 t2_idx ) */ count(data) 2 from t2; COUNT(DATA) ----------- 1040
  • 51. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | select /*+ index( t1 t1_idx ) */ count(data) from t1 call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.00 0.00 0 1044 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.00 0.00 0 1044 0 1 Misses in library cache during parse: 1 Optimizer mode: ALL_ROWS Parsing user id: 103 Number of plan statistics captured: 1 Rows (1st) Rows (avg) Rows (max) Row Source Operation ---------- ---------- ---------- ---------------------------------------------- 1 1 1 SORT AGGREGATE (cr=1044 pr=0 pw=0 time=1920 us 1040 1040 1040 TABLE ACCESS BY INDEX ROWID BATCHED T1 (cr=10 1040 1040 1040 INDEX FULL SCAN T1_IDX (cr=4 pr=0 pw=0 time= 1044-4 = 1040, the clustering factor of T1_IDX
  • 52. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | select /*+ index( t2 t2_idx ) */ count(data) from t2 call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.00 0.00 0 44 0 1 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 4 0.00 0.00 0 44 0 1 Misses in library cache during parse: 1 Optimizer mode: ALL_ROWS Parsing user id: 103 Number of plan statistics captured: 1 Rows (1st) Rows (avg) Rows (max) Row Source Operation ---------- ---------- ---------- ---------------------------------------------- 1 1 1 SORT AGGREGATE (cr=44 pr=0 pw=0 time=1004 us) 1040 1040 1040 TABLE ACCESS BY INDEX ROWID BATCHED T2 (cr=44 1040 1040 1040 INDEX FULL SCAN T2_IDX (cr=4 pr=0 pw=0 time= 44-4 = 40, the clustering factor of T2_IDX
  • 53. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> select count(data) 2 from t1 3 where key between 'A00000' and 'A00250'; COUNT(DATA) ----------- 9 TKYTE@ORA12C> select * from table(dbms_xplan.display_cursor); ------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| ------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | 12 (100)| | 1 | SORT AGGREGATE | | 1 | 268 | | | 2 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 9 | 2412 | 12 (0)| |* 3 | INDEX RANGE SCAN | T1_IDX | 9 | | 2 (0)| ------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("KEY">='A00000' AND "KEY"<='A00250')
  • 54. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> select count(data) 2 from t2 3 where key between 'A00000' and 'A00250'; COUNT(DATA) ----------- 9 TKYTE@ORA12C> select * from table(dbms_xplan.display_cursor); ------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| ------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | 3 (100)| | 1 | SORT AGGREGATE | | 1 | 268 | | | 2 | TABLE ACCESS BY INDEX ROWID BATCHED| T2 | 9 | 2412 | 3 (0)| |* 3 | INDEX RANGE SCAN | T2_IDX | 9 | | 2 (0)| ------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("KEY">='A00000' AND "KEY"<='A00250')
  • 55. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> select count(data) 2 from t1 3 where key between 'A00000' and 'A00500'; COUNT(DATA) ----------- 19 TKYTE@ORA12C> select * from table(dbms_xplan.display_cursor); --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 14 (100)| | | 1 | SORT AGGREGATE | | 1 | 268 | | | |* 2 | TABLE ACCESS FULL| T1 | 20 | 5360 | 14 (0)| 00:00:01 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(("KEY"<='A00500' AND "KEY">='A00000'))
  • 56. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> select count(data) 2 from t2 3 where key between 'A00000' and 'A00500'; COUNT(DATA) ----------- 19 TKYTE@ORA12C> select * from table(dbms_xplan.display_cursor); ------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| ------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | 3 (100)| | 1 | SORT AGGREGATE | | 1 | 268 | | | 2 | TABLE ACCESS BY INDEX ROWID BATCHED| T2 | 20 | 5360 | 3 (0)| |* 3 | INDEX RANGE SCAN | T2_IDX | 20 | | 2 (0)| ------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("KEY">='A00000' AND "KEY"<='A00500')
  • 57. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> begin 2 dbms_stats.set_table_prefs 3 ( ownname => user, 4 tabname => 'T1', 5 pname => 'TABLE_CACHED_BLOCKS', 6 pvalue => 42 ); 7 dbms_stats.set_table_prefs 8 ( ownname => user, 9 tabname => 'T2', 10 pname => 'TABLE_CACHED_BLOCKS', 11 pvalue => 42 ); 12 13 dbms_stats.gather_index_stats( user, 'T1_IDX' ); 14 dbms_stats.gather_index_stats( user, 'T2_IDX' ); 15 end; 16 / PL/SQL procedure successfully completed.
  • 58. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE@ORA12C> select table_name, index_name, clustering_factor, to_char(last_analyzed,'dd-mon hh24:mi:ss') la 2 from user_indexes 3 where table_name in ('T1','T2') 4 order by 1; TABLE_NAME INDEX_NAME CLUSTERING_FACTOR LA -------------------- -------------------- ----------------- --------------- T1 T1_IDX 40 25-sep 17:34:36 T2 T2_IDX 40 25-sep 17:34:36
  • 59. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Program Agenda The optimizer is learning from its mistakes Functions used, without using a Function PL/SQL warned you Location, Location, Location The most underutilized really cool feature (from five years ago!) 1 2 3 4 5
  • 60. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Quick Story… I’m going to write a PL/SQL parser…
  • 61. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE%ORA12C> create user demo 2 identified by demo; User created. TKYTE%ORA12C> grant create session, 2 create procedure 3 to demo; Grant succeeded. TKYTE%ORA12C> create edition version2 2 as child of ora$base; Edition created.
  • 62. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE%ORA12C> connect demo/demo Connected. DEMO%ORA12C> create or replace 2 procedure my_procedure 3 as 4 begin 5 dbms_output.put_line( 'I am buggy version 1.0' ); 6 end; 7 / Procedure created. DEMO%ORA12C> create or replace 2 procedure my_procedure2 3 as 4 begin 5 my_procedure; 6 end; 7 / Procedure created.
  • 63. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | DEMO%ORA12C> exec my_procedure2 I am buggy version 1.0 PL/SQL procedure successfully completed.
  • 64. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | DEMO%ORA12C> alter session 2 set edition = version2; ERROR: ORA-38802: edition does not exist
  • 65. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | DEMO%ORA12C> connect tkyte/tkyte Connected. TKYTE%ORA12C> alter user demo 2 enable editions; User altered. TKYTE%ORA12C> grant use 2 on edition version2 3 to demo; Grant succeeded. TKYTE%ORA12C> grant use 2 on edition version2 3 to scott; Grant succeeded.
  • 66. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | TKYTE%ORA12C> connect demo/demo Connected. DEMO%ORA12C> alter session 2 set edition = version2; Session altered. DEMO%ORA12C> select object_name, object_type, status, edition_name 2 from user_objects; OBJECT_NAME OBJECT_TYPE STATUS EDITION_NAME ------------------------------ ----------- ------ ------------ MY_PROCEDURE PROCEDURE VALID ORA$BASE MY_PROCEDURE2 PROCEDURE VALID ORA$BASE
  • 67. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | DEMO%ORA12C> create or replace 2 procedure my_procedure 3 as 4 begin 5 dbms_output.put_line( 'I am fixed in version 2.0' ); 6 end; 7 / Procedure created.
  • 68. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | DEMO%ORA12C> select object_name, edition_name 2 from user_objects; OBJECT_NAME EDITION_NAME ------------------------------ ------------ MY_PROCEDURE2 ORA$BASE MY_PROCEDURE VERSION2 DEMO%ORA12C> select object_name, edition_name 2 from user_objects_AE; OBJECT_NAME EDITION_NAME ------------------------------ ------------ MY_PROCEDURE ORA$BASE MY_PROCEDURE2 ORA$BASE MY_PROCEDURE VERSION2
  • 69. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | DEMO%ORA12C> grant execute on my_procedure2 to scott; Grant succeeded. DEMO%ORA12C> select object_name, edition_name from user_objects; OBJECT_NAME EDITION_NAME ------------------------------ ------------ MY_PROCEDURE2 VERSION2 MY_PROCEDURE VERSION2 DEMO%ORA12C> select object_name, edition_name from user_objects_AE; OBJECT_NAME EDITION_NAME ------------------------------ ------------ MY_PROCEDURE2 ORA$BASE MY_PROCEDURE ORA$BASE MY_PROCEDURE2 VERSION2 MY_PROCEDURE VERSION2
  • 70. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | DEMO%ORA12C> SELECT SYS_CONTEXT ('userenv', 'current_edition_name') sc 2 FROM DUAL; SC --------------- VERSION2 DEMO%ORA12C> exec my_procedure2 I am fixed in version 2.0 PL/SQL procedure successfully completed.
  • 71. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | DEMO%ORA12C> connect demo/demo Connected. DEMO%ORA12C> SELECT SYS_CONTEXT ('userenv', 'current_edition_name') sc 2 FROM DUAL; SC --------------- ORA$BASE DEMO%ORA12C> exec my_procedure2 I am buggy version 1.0 PL/SQL procedure successfully completed.
  • 72. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | DEMO%ORA12C> alter session set edition = version2; Session altered. DEMO%ORA12C> SELECT SYS_CONTEXT ('userenv', 'current_edition_name') sc 2 FROM DUAL; SC --------------- VERSION2 DEMO%ORA12C> exec my_procedure2 I am fixed in version 2.0 PL/SQL procedure successfully completed.
  • 73. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | DEMO%ORA12C> connect scott/tiger Connected. SCOTT%ORA12C> SELECT SYS_CONTEXT ('userenv', 'current_edition_name') sc 2 FROM DUAL; SC --------------- ORA$BASE SCOTT%ORA12C> exec demo.my_procedure2 BEGIN demo.my_procedure2; END; * ERROR at line 1: ORA-06550: line 1, column 7: PLS-00201: identifier 'DEMO.MY_PROCEDURE2' must be declared ORA-06550: line 1, column 7: PL/SQL: Statement ignored
  • 74. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | SCOTT%ORA12C> alter session 2 set edition = version2; Session altered. SCOTT%ORA12C> exec demo.my_procedure2 I am fixed in version 2.0 PL/SQL procedure successfully completed.
  • 75. Copyright © 2014, Oracle and/or its affiliates. All rights reserved. | Program Agenda The optimizer is learning from its mistakes Functions used, without using a Function PL/SQL warned you Location, Location, Location The most underutilized really cool feature (from five years ago!) 1 2 3 4 5