The autonomous database offers insane levels of performance, but you won't be able to attain that if you are not constructing your SQL statements in a way that is scalable...and more importantly, secure from hacking
Apologies for most pics missing and awful layout...you can thank slideshare for that :-(
11. 26/11/2019
11
~2007
42
"why do I care?"
43
you can't blame the server (anymore)
44
if you can't get that performance ...
41 42
43 44
12. 26/11/2019
12
45
... it's you
47
"The sooner your company admits that you are not
Google, the sooner you can get down to some real
work"
- Ted Dziuba
48
so what's holding you back ?
45 46
47 48
13. 26/11/2019
13
49
It all comes down to...
50
too much work or ...
51
... not being able to do work
52
PART #1
5
2
compiling SQL
49 50
51 52
14. 26/11/2019
14
53
... how to avoid work when processing SQL
54
terminology
55
cursorsdeclare
cursor C(p number) is
select * from DEPT
where DEPTNO = p;
begin
for rec in C loop
…
end loop;
end;
select *
from EMPLOYEE
where EMPNO > 1234;
delete from MY_TABLE;
drop table MY_TABLE;
begin
MY_PROCEDURE(1,2,3);
end;
56
all of them !
53 54
55 56
15. 26/11/2019
15
57
3 phases
58
open
process
close
gimme some memory
do some stuff using that memory,
maybe access other memory
here's your memory back
59
memory access = controlled access
60
a quick primer on (database) memory
57 58
59 60
20. 26/11/2019
20
77
active wait
78
spinning
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
can I have the latch ?
77 78
79 80
23. 26/11/2019
23
89
to run a SQL statement
90
Syntax
Validity
Optimization
Rowsourcing
Execution
(Fetch)
SQL> select *
2 frmo emp;
frmo emp
*
ERROR at line 2:
ORA-00923: FROM keyword not found where expected
91
Syntax
Validity
Optimization
Rowsourcing
Execution
(Fetch)
SQL> select empnoo
2 from emp;
select empnoo
*
ERROR at line 1:
ORA-00904: invalid column name
92
PLAN
-------------------------------------
SELECT STATEMENT
TABLE ACCESS BY INDEX ROWID EMP
INDEX RANGE SCAN EMP_PK
Syntax
Validity
Optimization
Rowsourcing
Execution
(Fetch)
89 90
91 92
26. 26/11/2019
26
101
library cache
102
previously executed
statements
103
parse statement
already in library cache ?
reuse optimizer info
reuse row source info
select * from emp where empno = 123
syntactically, semantics OK
104
select surname, firstname from emp where empno = 123
select * from dept where deptno = 4567
select * from customer where locality = 17
select prno from property where reference = 'X123G'
select * from dept where deptno = 23
select surname, firstname from emp where empno = 123
select * from customer where locality = 256
select * from organisation where officer = 'OFF876'
select surname, firstname from emp where empno = 7632
select * from dept where deptno = 4567
select offender from crimes where crno = 247462
Two full parses avoided
library
cache
101 102
103 104
27. 26/11/2019
27
105
select surname, firstname from emp where empno = 123
select * from dept where dname = 'SALES'
probability of reuse low ?
106
some queries are “nearly the same”
select surname, firstname from emp where empno = 123
select surname, firstname from emp where empno = 456
107
binding
parse this...
now run it with ? = 123
now run it with ? = 456
select surname, firstname from emp where empno = ?
108
select surname, firstname from emp where empno = ?
select * from dept where deptno = ?
select * from customer where locality = ?
select prno from property where reference = ?
select * from dept where deptno = ?
select surname, firstname from emp where empno = ?
select * from customer where locality = ?
select * from organisation where officer = ?
select surname, firstname from emp where empno = ?
select * from dept where deptno = ?
select offender from crimes where crno = ?
Five full parses avoided
library
cache
105 106
107 108
29. 26/11/2019
29
113
building SQL by concatenation
114
you'll get hacked
115
select ename
from emp
where empno = 6543
select ename
from emp
where empno = 6543
and 1=0
union all
select table_name
from all_tables
where table_name like '%SECURITY%'
select ename
from emp
where empno = 6543
and 1=0
union all
select username
from app_security
where ...
116
it takes 5 minutes to hack you
113 114
115 116
30. 26/11/2019
30
117
for fast, secure SQL ...
118
... always bind user input
119
"I'm an APEX developer... not an issue"
120
117 118
119 120
31. 26/11/2019
31
121
other common culprits
item protection
create_collection_from_query
122
while we are talking binding
123
parse statement
already in library cache ?
reuse optimizer info
reuse row source info
select * from emp where empno = 123
syntactically, semantics OK
Yes!
Yes!
???
???
124
still some parsing to do
121 122
123 124
33. 26/11/2019
33
129
your SQL is always shareable
library cache
select *
from emp
130
your cursor points to it
cursor
library cache
select *
from emp
131
close cursor = lose pointer
cursor
library cache
select *
from emp
132
next time we parse
soft parse
129 130
131 132
34. 26/11/2019
34
133
what if we don't close the cursor
134
emplist(String[] args) {
if "first time I'm using this" {
else
"reset the pointer, re-execute"
}
library cache
select *
from emp
select *
from dept
select *
from emp
where ...
pstmt_all_emp =
con.prepareStatement("select * from emp");
cursor
cursor
cursor
135
don’t close the cursorhang on to the memoryremember what cursors we’ve usedreuse whenever possibledon’t exhaust memorydon’t allow invalid cursor reuse
136
sounds complicated ...
133 134
135 136
35. 26/11/2019
35
137
a free solution exists
138
plsql
139
create procedure MY_PROC is
begin
select empno, ename, ...
into …
from emp
where empno = my_plsql_variable
...
end;
140
static SQL in stored PLSQL
automatically uses bind variables
hold’s cursors open
(even if you close)
137 138
139 140
36. 26/11/2019
36
141
procedure MY_PROC is
cursor c_emp is
select * from emp;
begin
open c_emp;
fetch c_emp
into …;
close c_emp;
end;
select * from emp
procedure MY_PROC is
begin
select *
into …
from dept
where …
end;
select * from dept …
142
PART #2
get | store results
we'll come back to running SQL
143 144
start with reading data
141 142
143 144
37. 26/11/2019
37
145
querying data
146
data is stored in blocks | pages
147
to read data, you read blocks...
148
SQL> select *
2 from EMP
3 where ...
/u01/my_data1.dat
memory
145 146
147 148
38. 26/11/2019
38
149
but (database) memory access is complex
150
SQL> select *
2 from EMP
3 where …
SQL> update EMP
2 set …
3 where …
SQL> select *
2 from EMP
3 where …
SQL> insert into
2 EMP
3 values (…)
SQL> select *
2 from CUSTOMER
3 /
SQL> select max(EMPNO)
2 from EMP
SQL> delete
2 from DEPT
3 /
151
we have to latch !
152
• Get latch
• Search along list of blocks in memory
• Read block
• Extract row of interest
• Release latch
• Give row back to client
"fetch a row"
149 150
151 152
39. 26/11/2019
39
153
lots of rows
154
lots of latching
155
typical program
156
rs = stmt.executeQuery("...");
while(rs.next()) {
v1 = rs.getInt(1);
v2 = rs.getString(2);
...
}
• Get latch
• Walk along list
• Get block
• Extract single row
• Release latch
• Give row back to client
• Get latch (again)
• Walk along list (again)
• Get block (again)
• Extract single row
• Release latch (again)
• Give row back to client (again)
Row #1
Row #2
• Get latch (again)
• Walk along list (again)
• Get block (again)
• Extract single row
• Release latch (again)
• Give row back to client (again)
Row #3
153 154
155 156
40. 26/11/2019
40
157
a better strategy.... “pinning”
158
"fetch a row"
• Get latch
• Walk along list
• Get block
• Pin the block
• Release latch
• Give row 1 back to client
• Give row 2 back to client
…
• Give row n to client
• Get latch
• Walk along list
• Remove my pin on the block
• Release latch
“and .. I’ll will need
several rows from
this block”
159
how do you say
“I may want many rows” ?
160
responsibility of the client
157 158
159 160
42. 26/11/2019
42
165
SQL> declare
cursor C is select ... (500m table)
...
9 begin
10 open c;
11 loop
12 fetch c
13 into r;
14 exit when c%notfound;
. . .
19 /
Elapsed: 00:01:11.72
166
SQL> declare
cursor C is select ... (500m table)
. . .
9 begin
10 open c;
11
12 fetch c
13 bulk collect
14 into r;
15
. . .
19 /
Elapsed: 00:00:08.93
167
SQL> select * from v$mystats
2 where name like '%pga%'
3 /
NAME VALUE
------------------------------ ----------
session pga memory 501534672
session pga memory max 501534672
168
500m of memory !
165 166
167 168
43. 26/11/2019
43
169
law of diminishing returns
170
pin rows on a block (8k)
171
SQL> declare
. . .
9 begin
10 open c;
11 loop
12 fetch c
13 bulk collect
14 into r limit 100;
15 exit when c%notfound;
. . .
19 /
Elapsed: 00:00:08.17
NAME VALUE
------------------------------ ----------
session pga memory 625912
session pga memory max 625912
172
SQL> declare
. . .
9 begin
10 for i in c loop
12 ...
16 end loop;
17 end;
18 /
Elapsed: 00:00:08.21
169 170
171 172
47. 26/11/2019
47
185
using PLSQL is golden
186
and you can do it all .... for free
oracle.com/gbtour
New Free Tier
Always Free
Oracle Cloud Infrastructure
Services you can use for unlimited time
30-Day Free Trial
Free credits you can use for more services
+
Thanks for coming!
connor-mcdonald.com
https://bit.ly/techguysong
185 186
187 188