SlideShare a Scribd company logo
1 of 76
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

Similar to Five more things about Oracle SQL and PLSQL

D73549GC10_06.pptx
D73549GC10_06.pptxD73549GC10_06.pptx
D73549GC10_06.pptx
VLQuyNhn
 

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

More than 12 More things about Oracle Database 12c
More than 12 More things about Oracle Database 12cMore than 12 More things about Oracle Database 12c
More than 12 More things about Oracle Database 12c
 
New index features in MySQL 8
New index features in MySQL 8New index features in MySQL 8
New index features in MySQL 8
 
Wellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
Wellington APAC Groundbreakers tour - Upgrading to the 12c OptimizerWellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
Wellington APAC Groundbreakers tour - Upgrading to the 12c Optimizer
 
D73549GC10_06.pptx
D73549GC10_06.pptxD73549GC10_06.pptx
D73549GC10_06.pptx
 
Mysql Performance Schema - fossasia 2016
Mysql Performance Schema - fossasia 2016Mysql Performance Schema - fossasia 2016
Mysql Performance Schema - fossasia 2016
 
MySQL-Performance Schema- What's new in MySQL-5.7 DMRs
MySQL-Performance Schema- What's new in MySQL-5.7 DMRsMySQL-Performance Schema- What's new in MySQL-5.7 DMRs
MySQL-Performance Schema- What's new in MySQL-5.7 DMRs
 
Sql and PL/SQL Best Practices I
Sql and PL/SQL Best Practices ISql and PL/SQL Best Practices I
Sql and PL/SQL Best Practices I
 
OpenWorld 2018 - SQL Tuning in 20 mins
OpenWorld 2018 - SQL Tuning in 20 minsOpenWorld 2018 - SQL Tuning in 20 mins
OpenWorld 2018 - SQL Tuning in 20 mins
 
Whats new in Oracle Trace File analyzer 18.3.0
Whats new in Oracle Trace File analyzer 18.3.0Whats new in Oracle Trace File analyzer 18.3.0
Whats new in Oracle Trace File analyzer 18.3.0
 
Whats new in oracle trace file analyzer 18.3.0
Whats new in oracle trace file analyzer 18.3.0Whats new in oracle trace file analyzer 18.3.0
Whats new in oracle trace file analyzer 18.3.0
 
18c and 19c features for DBAs
18c and 19c features for DBAs18c and 19c features for DBAs
18c and 19c features for DBAs
 
What's new in oracle trace file analyzer 18.2.0
What's new in oracle trace file analyzer 18.2.0What's new in oracle trace file analyzer 18.2.0
What's new in oracle trace file analyzer 18.2.0
 
Getting optimal performance from oracle e business suite
Getting optimal performance from oracle e business suiteGetting optimal performance from oracle e business suite
Getting optimal performance from oracle e business suite
 
Trace File Analyzer - Usage and Features
Trace File Analyzer - Usage and Features Trace File Analyzer - Usage and Features
Trace File Analyzer - Usage and Features
 
Oracle Trace File Analyzer Overview
Oracle Trace File Analyzer OverviewOracle Trace File Analyzer Overview
Oracle Trace File Analyzer Overview
 
Getting optimal performance from oracle e-business suite presentation
Getting optimal performance from oracle e-business suite presentationGetting optimal performance from oracle e-business suite presentation
Getting optimal performance from oracle e-business suite presentation
 
OpenWorld 2018 - 20 years of hints and tips
OpenWorld 2018 - 20 years of hints and tipsOpenWorld 2018 - 20 years of hints and tips
OpenWorld 2018 - 20 years of hints and tips
 
Oracle no sql release 3 4 overview
Oracle no sql release 3 4 overviewOracle no sql release 3 4 overview
Oracle no sql release 3 4 overview
 
MySQL Performance Schema, Open Source India, 2015
MySQL Performance Schema, Open Source India, 2015MySQL Performance Schema, Open Source India, 2015
MySQL Performance Schema, Open Source India, 2015
 
ORAchk EXAchk what's new in 12.1.0.2.7
ORAchk EXAchk what's new in 12.1.0.2.7ORAchk EXAchk what's new in 12.1.0.2.7
ORAchk EXAchk what's new in 12.1.0.2.7
 

More from Connor McDonald

More from Connor McDonald (20)

Flashback ITOUG
Flashback ITOUGFlashback ITOUG
Flashback ITOUG
 
Sangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolestSangam 19 - PLSQL still the coolest
Sangam 19 - PLSQL still the coolest
 
Sangam 19 - Analytic SQL
Sangam 19 - Analytic SQLSangam 19 - Analytic SQL
Sangam 19 - Analytic SQL
 
UKOUG - 25 years of hints and tips
UKOUG - 25 years of hints and tipsUKOUG - 25 years of hints and tips
UKOUG - 25 years of hints and tips
 
Sangam 19 - Successful Applications on Autonomous
Sangam 19 - Successful Applications on AutonomousSangam 19 - Successful Applications on Autonomous
Sangam 19 - Successful Applications on Autonomous
 
Sangam 2019 - The Latest Features
Sangam 2019 - The Latest FeaturesSangam 2019 - The Latest Features
Sangam 2019 - The Latest Features
 
UKOUG 2019 - SQL features
UKOUG 2019 - SQL featuresUKOUG 2019 - SQL features
UKOUG 2019 - SQL features
 
APEX tour 2019 - successful development with autonomous
APEX tour 2019 - successful development with autonomousAPEX tour 2019 - successful development with autonomous
APEX tour 2019 - successful development with autonomous
 
APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne APAC Groundbreakers 2019 - Perth/Melbourne
APAC Groundbreakers 2019 - Perth/Melbourne
 
OOW19 - Flashback, not just for DBAs
OOW19 - Flashback, not just for DBAsOOW19 - Flashback, not just for DBAs
OOW19 - Flashback, not just for DBAs
 
OOW19 - Read consistency
OOW19 - Read consistencyOOW19 - Read consistency
OOW19 - Read consistency
 
OOW19 - Slower and less secure applications
OOW19 - Slower and less secure applicationsOOW19 - Slower and less secure applications
OOW19 - Slower and less secure applications
 
OOW19 - Killing database sessions
OOW19 - Killing database sessionsOOW19 - Killing database sessions
OOW19 - Killing database sessions
 
OOW19 - Ten Amazing SQL features
OOW19 - Ten Amazing SQL featuresOOW19 - Ten Amazing SQL features
OOW19 - Ten Amazing SQL features
 
Latin America Tour 2019 - 18c and 19c featues
Latin America Tour 2019   - 18c and 19c featuesLatin America Tour 2019   - 18c and 19c featues
Latin America Tour 2019 - 18c and 19c featues
 
Latin America tour 2019 - Flashback
Latin America tour 2019 -  FlashbackLatin America tour 2019 -  Flashback
Latin America tour 2019 - Flashback
 
Latin America Tour 2019 - 10 great sql features
Latin America Tour 2019  - 10 great sql featuresLatin America Tour 2019  - 10 great sql features
Latin America Tour 2019 - 10 great sql features
 
Latin America Tour 2019 - pattern matching
Latin America Tour 2019 - pattern matchingLatin America Tour 2019 - pattern matching
Latin America Tour 2019 - pattern matching
 
Latin America Tour 2019 - slow data and sql processing
Latin America Tour 2019  - slow data and sql processingLatin America Tour 2019  - slow data and sql processing
Latin America Tour 2019 - slow data and sql processing
 
ANSI vs Oracle language
ANSI vs Oracle languageANSI vs Oracle language
ANSI vs Oracle language
 

Recently uploaded

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Recently uploaded (20)

08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

Five more things about Oracle SQL and PLSQL

  • 1.
  • 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