Skip to content

Commit a44dc44

Browse files
committed
Update to 18c and SE
1 parent ff55cd1 commit a44dc44

39 files changed

+2736
-50
lines changed

optimizer/spm_plan_control/README.md

100644100755
Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@ Based on <a href="https://blogs.oracle.com/optimizer/using-sql-plan-management-t
44

55
The example.sql script demonstrates how to control SQL execution plans using SQL plan management.
66

7-
The example2.sql calls "proc2.sql": a nice solution that adds a NEW SQL plan baselines and loads all other plans disabled.
7+
The example2.sql calls "proc2.sql": it adds a NEW SQL plan baselines and loads all other plans disabled.
8+
9+
Edit connect_admin.sql, connect_user.sql to suit you environment (e.g. MT or non-MT).
810

911
Scripts create utility procedures called "set_my_plan" and "add_my_plan" (see proc.sql and proc2.sql) that allows you to take a SQL execution plan from a test query and apply it to an application query.
1012

11-
Example output is shown in example.lst.
13+
Example output is shown in example.lst and example2.lst.
14+
15+
Note that example.sql example2.sql scripts will DROP AND CREATE a new user called SPM_TESTU.
1216

13-
Note that example.sql example2.sql scripts will create a new user called SPM_TESTU.
17+
Scripts tested in Oracle Database 11g Release 2, Oracle Database 12c Release 2 and Oracle Database 18c. The only caveat is that in Oracle Database 11g DBMS_XPLAN sometimes returns ORA-01403, but the example still works.
1418

15-
Scripts tested in Oracle Database 11g Release 2 and Oracle Database 12c Release 2. The only caveat is that in Oracle Database 11g DBMS_XPLAN sometimes returns ORA-01403, but the example still works.
19+
Now included: SPM example for Oracle Database 18c Standard Edition (see SE directory)
1620

1721

1822
DISCLAIMER:
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Demo for unpublished bug #27500184
2+
3+
In SE, cursor is repeatedly invalidated if a
4+
SQL plan baseline exists and a new plan
5+
has been found by the optimizer.
6+
7+
Create a DBA user. E.g. adhoc/adhoc
8+
9+
Log in to DBA user.
10+
11+
Run make_tc.sql
12+
13+
Next:
14+
@run
15+
Then:
16+
@run2
17+
18+
Spool files are included comparing the SE and EE runs.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--
2+
-- Drop existing SQL plan baselines (with HELLO in the text)
3+
--
4+
declare
5+
l_plans_dropped pls_integer;
6+
BEGIN
7+
for rec in (select distinct sql_handle from dba_sql_plan_baselines where sql_text like '%HELLO%' and creator = user)
8+
loop
9+
l_plans_dropped := dbms_spm.drop_sql_plan_baseline (
10+
sql_handle => rec.sql_handle,
11+
plan_name => null);
12+
end loop;
13+
end;
14+
/
Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
SQL> @make_tc
2+
USER is "ADHOC"
3+
SQL> --
4+
SQL> -- Drop existing SQL plan baselines (with HELLO in the text)
5+
SQL> --
6+
SQL> declare
7+
2 l_plans_dropped pls_integer;
8+
3 BEGIN
9+
4 for rec in (select distinct sql_handle from dba_sql_plan_baselines where sql_text like '%HELLO%' and creator = user)
10+
5 loop
11+
6 l_plans_dropped := dbms_spm.drop_sql_plan_baseline (
12+
7 sql_handle => rec.sql_handle,
13+
8 plan_name => null);
14+
9 end loop;
15+
10 end;
16+
11 /
17+
18+
PL/SQL procedure successfully completed.
19+
20+
SQL>
21+
SQL> --
22+
SQL> -- (Drop and) create a table BOB
23+
SQL> --
24+
SQL> drop table bob purge;
25+
26+
Table dropped.
27+
28+
SQL>
29+
SQL> create table bob (id number(10), num number(10));
30+
31+
Table created.
32+
33+
SQL>
34+
SQL> begin
35+
2 for i in 1..10000
36+
3 loop
37+
4 insert into bob values (i,i);
38+
5 end loop;
39+
6 end;
40+
7 /
41+
42+
PL/SQL procedure successfully completed.
43+
44+
SQL> commit;
45+
46+
Commit complete.
47+
48+
SQL>
49+
SQL> exec dbms_stats.gather_table_stats (ownname=>null,tabname=>'bob');
50+
51+
PL/SQL procedure successfully completed.
52+
53+
SQL>
54+
SQL> --
55+
SQL> -- This is the test query
56+
SQL> --
57+
SQL> select /* HELLO */ num from bob where id = 100;
58+
59+
NUM
60+
----------
61+
100
62+
63+
1 row selected.
64+
65+
SQL> select /* HELLO */ num from bob where id = 100;
66+
67+
NUM
68+
----------
69+
100
70+
71+
1 row selected.
72+
73+
SQL> select /* HELLO */ num from bob where id = 100;
74+
75+
NUM
76+
----------
77+
100
78+
79+
1 row selected.
80+
81+
SQL>
82+
SQL> --
83+
SQL> -- Load the query's plan to create a SQL plan baseline
84+
SQL> --
85+
SQL> var r number
86+
SQL> exec :r := dbms_spm.load_plans_from_cursor_cache('8c2dqym0cbqvj')
87+
88+
PL/SQL procedure successfully completed.
89+
90+
SQL>
91+
SQL> --
92+
SQL> -- Check that the SQL plan baseline exists
93+
SQL> --
94+
SQL> select sql_text,accepted,enabled,sql_handle,plan_name from dba_sql_plan_baselines where sql_text like '%HELLO%';
95+
96+
SQL_TEXT ACC ENA SQL_HANDLE PLAN_NAME
97+
-------------------------------------------------- --- --- ------------------------------ ------------------------------
98+
select /* HELLO */ num from bob where id = 100 YES YES SQL_d836e5d3c42a4dbd SQL_PLAN_dhdr5ug22nmdx03c729f0
99+
100+
1 row selected.
101+
102+
SQL>
103+
SQL> pause p...
104+
p...
105+
106+
SQL>
107+
SQL> --
108+
SQL> -- Check to see if the SQL statement is using the SQL plan baseline
109+
SQL> --
110+
SQL> select /* HELLO */ num from bob where id = 100;
111+
112+
NUM
113+
----------
114+
100
115+
116+
1 row selected.
117+
118+
SQL> select * from table(dbms_xplan.display_cursor(format=>'TYPICAL'));
119+
120+
PLAN_TABLE_OUTPUT
121+
------------------------------------------------------------------------------------------------------------------------------------------------------
122+
SQL_ID 8c2dqym0cbqvj, child number 0
123+
-------------------------------------
124+
select /* HELLO */ num from bob where id = 100
125+
126+
Plan hash value: 1006760864
127+
128+
--------------------------------------------------------------------------
129+
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
130+
--------------------------------------------------------------------------
131+
| 0 | SELECT STATEMENT | | | | 7 (100)| |
132+
|* 1 | TABLE ACCESS FULL| BOB | 1 | 8 | 7 (0)| 00:00:01 |
133+
--------------------------------------------------------------------------
134+
135+
Predicate Information (identified by operation id):
136+
---------------------------------------------------
137+
138+
1 - filter("ID"=100)
139+
140+
Note
141+
-----
142+
- SQL plan baseline SQL_PLAN_dhdr5ug22nmdx03c729f0 used for this statement
143+
144+
145+
22 rows selected.
146+
147+
SQL>
148+
SQL> pause p...
149+
p...
150+
151+
SQL>
152+
SQL> --
153+
SQL> -- Creating the index will give us the potential to use a new INDEX plan
154+
SQL> -- but the SQL plan baseline will prevent this
155+
SQL> --
156+
SQL> create unique index bobi on bob(id);
157+
158+
Index created.
159+
160+
SQL>
161+
SQL> --
162+
SQL> -- Execute again - the INDEX plan is available but SPM prevents its use
163+
SQL> --
164+
SQL> select /* HELLO */ num from bob where id = 100;
165+
166+
NUM
167+
----------
168+
100
169+
170+
1 row selected.
171+
172+
SQL> select /* HELLO */ num from bob where id = 100;
173+
174+
NUM
175+
----------
176+
100
177+
178+
1 row selected.
179+
180+
SQL> select /* HELLO */ num from bob where id = 100;
181+
182+
NUM
183+
----------
184+
100
185+
186+
1 row selected.
187+
188+
SQL> select /* HELLO */ num from bob where id = 100;
189+
190+
NUM
191+
----------
192+
100
193+
194+
1 row selected.
195+
196+
SQL> select /* HELLO */ num from bob where id = 100;
197+
198+
NUM
199+
----------
200+
100
201+
202+
1 row selected.
203+
204+
SQL> --
205+
SQL> -- SE: Plan is not available because cursor is being invalidated
206+
SQL> -- EE: Plan is available
207+
SQL> --
208+
SQL> select * from table(dbms_xplan.display_cursor(format=>'TYPICAL'));
209+
210+
PLAN_TABLE_OUTPUT
211+
------------------------------------------------------------------------------------------------------------------------------------------------------
212+
SQL_ID 8c2dqym0cbqvj, child number 1
213+
-------------------------------------
214+
select /* HELLO */ num from bob where id = 100
215+
216+
Plan hash value: 1006760864
217+
218+
--------------------------------------------------------------------------
219+
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
220+
--------------------------------------------------------------------------
221+
| 0 | SELECT STATEMENT | | | | 7 (100)| |
222+
|* 1 | TABLE ACCESS FULL| BOB | 1 | 8 | 7 (0)| 00:00:01 |
223+
--------------------------------------------------------------------------
224+
225+
Predicate Information (identified by operation id):
226+
---------------------------------------------------
227+
228+
1 - filter("ID"=100)
229+
230+
Note
231+
-----
232+
- SQL plan baseline SQL_PLAN_dhdr5ug22nmdx03c729f0 used for this statement
233+
234+
235+
22 rows selected.
236+
237+
SQL> pause p...
238+
p...
239+
240+
SQL> --
241+
SQL> -- Check V$SQL
242+
SQL> -- SE: Not visible
243+
SQL> -- EE: Visible
244+
SQL> --
245+
SQL> select sql_id from v$sql where sql_text = 'select /* HELLO */ num from bob where id = 100';
246+
247+
SQL_ID
248+
-------------
249+
8c2dqym0cbqvj
250+
251+
1 row selected.
252+
253+
SQL>
254+
SQL> pause p...
255+
p...
256+
257+
SQL> --
258+
SQL> -- Check V$SQL_SHARED_CURSOR
259+
SQL> --
260+
SQL> select * from v$sql_shared_cursor where sql_id = '8c2dqym0cbqvj' order by child_number;
261+
262+
SQL_ID ADDRESS CHILD_ADDRESS CHILD_NUMBER U S O O S L F E B P I S T A B D L T B I I R L I O E M U T N F A P T D L D B P C S C P T M B M R O P M F L P L A F L R L H P B U REASON CON_ID
263+
------------- ---------------- ---------------- ------------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -------------------------------------------------------------------------------- ----------
264+
8c2dqym0cbqvj 0000000061645A10 0000000061380238 1 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N 0
265+
266+
1 row selected.
267+
268+
SQL>
269+
SQL> pause p...
270+
p...
271+
272+
SQL>
273+
SQL> --
274+
SQL> -- In SE there will be a single SQL plan baseline
275+
SQL> -- In EE, there will be two SQL plan baselines - the new INDEX plan is ready for evolution
276+
SQL> --
277+
SQL> select sql_text,accepted,enabled,sql_handle,plan_name from dba_sql_plan_baselines;
278+
279+
SQL_TEXT ACC ENA SQL_HANDLE PLAN_NAME
280+
-------------------------------------------------- --- --- ------------------------------ ------------------------------
281+
select /* HELLO */ num from bob where id = 100 YES YES SQL_d836e5d3c42a4dbd SQL_PLAN_dhdr5ug22nmdx03c729f0
282+
select /* HELLO */ num from bob where id = 100 NO YES SQL_d836e5d3c42a4dbd SQL_PLAN_dhdr5ug22nmdx6934a678
283+
284+
2 rows selected.
285+
286+
SQL>
287+
SQL> show user
288+
USER is "ADHOC"
289+
SQL> spool off

0 commit comments

Comments
 (0)