-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathogb2.sql
More file actions
393 lines (351 loc) · 9.2 KB
/
ogb2.sql
File metadata and controls
393 lines (351 loc) · 9.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
REM
REM Standard disclaimer - anything in here can be used at your own risk.
REM
REM It is very likely you'll need to edit the script for correct usernames/passwords etc.
REM
REM No warranty or liability etc etc etc. See the license file in the git repo root
REM
REM *** USE AT YOUR OWN RISK ***
REM
set echo off
set termout off
conn / as sysdba
set termout off
--
-- we don't want results biased by a log switch in the middle of things or
-- differences in buffer cache etc, so we flush everything
--
alter system archive log current;
alter system checkpoint;
conn /@YOURDB as sysdba
set termout off
--
-- we have to turn off dynamic sequencing in order to show its benefit later
--
alter system set "_dynamic_sequence_cache" = false;
conn ogb/ogb@YOURDB
set termout off
alter session set "_dynamic_sequence_cache" = false;
--
-- baseline, triggers plus indexes plus bad seq
--
@drop results
@drop customers
@drop order_items
@drop orders
@drop product_categories
@drop products
@drop customers_seq;
@drop product_seq;
@drop orders_seq;
clear screen
@clean
set echo on
create table customers (
customer_id integer not null,
customer_ssn varchar2(20 char) not null,
customer_name varchar2(100 char) not null,
created_by varchar2(128) not null
);
alter table customers add constraint customer_pk primary key ( customer_id );
alter table customers add constraint customer_ssn_u unique ( customer_ssn );
create table product_categories (
category_name varchar2(20) not null
);
alter table product_categories add constraint product_categories_pk primary key ( category_name );
pause
clear screen
create table products (
product_id integer not null,
product_description_json clob not null check ( product_description_json is json ),
price number not null,
category_name varchar2(20) not null,
product_name varchar2(100) not null
);
alter table products add constraint products_pk primary key ( product_id );
pause
create table orders (
order_id integer not null,
order_datetime date not null,
customer_id integer not null,
created_by varchar2(128) not null
);
alter table orders add constraint order_pk primary key ( order_id );
create index orders_ix1 on orders ( customer_id );
pause
clear screen
create table order_items (
order_id integer not null,
product_id integer not null,
quantity integer not null,
unit_price number(10, 2) not null,
created_by varchar2(128) not null
);
alter table order_items add constraint order_items_pk
primary key ( order_id, product_id );
create index order_items_ix1 on order_items ( order_id );
create index order_items_ix2 on order_items ( product_id );
pause
clear screen
alter table orders
add constraint order_customer_fk foreign key ( customer_id )
references customers ( customer_id );
alter table order_items
add constraint order_items_order_fk foreign key ( order_id )
references orders ( order_id );
alter table order_items
add constraint order_items_products_fk foreign key ( product_id )
references products ( product_id );
alter table products
add constraint products_product_categories_fk foreign key ( category_name )
references product_categories ( category_name );
pause
clear screen
create sequence customers_seq;
create sequence product_seq;
create sequence orders_seq;
pause
clear screen
create or replace
trigger customer_trg
before insert on customers
for each row
begin
if :new.customer_id is null then
:new.customer_id := customers_seq.nextval;
end if;
if :new.created_by is null then
:new.created_by := user;
end if;
end;
/
pause
clear screen
create or replace
trigger orders_trg
before insert on orders
for each row
begin
if :new.order_id is null then
:new.order_id := orders_seq.nextval;
end if;
if :new.order_datetime is null then
:new.order_datetime := sysdate;
end if;
if :new.created_by is null then
:new.created_by := user;
end if;
end;
/
pause
clear screen
create or replace
trigger order_items_trg
before insert on order_items
for each row
begin
if :new.created_by is null then
:new.created_by := user;
end if;
end;
/
pause
clear screen
insert into customers ( customer_ssn ,customer_name )
select 'custssn'||rownum, 'customer'||rownum
from dual
connect by level <= 5000;
insert into product_categories
select 'cat'||rownum
from dual
connect by level <= 20;
insert into products
select rownum,
'{"product":"my product'||rownum||'"}',
round(dbms_random.value(10,40),2),
'cat'||(mod(rownum,20)+1),
'product'||rownum
from dual
connect by level <= 1000;
commit;
pause
clear screen
create or replace
procedure new_order(p_customer_id int,
p_order_id out int) is
begin
insert into orders ( customer_id)
values ( p_customer_id)
returning order_id into p_order_id;
end;
/
create or replace
procedure new_customer(p_customer_ssn varchar2,
p_customer_name varchar2,
p_cust_id out int) is
begin
insert into customers ( customer_ssn ,customer_name )
values ( p_customer_ssn ,p_customer_name )
returning customer_id into p_cust_id;
end;
/
pause
create or replace
procedure new_order_item(p_order_id int, p_product_id int, p_quantity int, p_unit_price number ) is
begin
insert into order_items (order_id,product_id,quantity,unit_price)
values (p_order_id,p_product_id,p_quantity,p_unit_price);
end;
/
pause
clear screen
create table results as select rownum-1 seed, 0 tps, 0 ela from dual
connect by level <= 10;
pause
create or replace
package benchmark is
iter int := 40000; -- ORDERS TO PLACE
new_cust int := 200; -- NEW CUST EVERY 200 ORDERS
rnd int := 50000;
idx int;
seed int;
l_start timestamp;
l_order_id int;
l_cust_id int;
type numlist is table of number
index by pls_integer;
type charlist is table of varchar2(20)
index by pls_integer;
l_cust numlist;
l_prod numlist;
l_cat charlist;
l_item_cnt numlist;
l_lock int;
procedure init(p_seed int);
procedure run(p_seed int);
end;
/
pause
clear screen
create or replace
package body benchmark is
procedure init(p_seed int) is
begin
seed := p_seed;
dbms_random.seed(p_seed);
select mod(rownum,5000)+1 bulk collect into l_cust
from dual connect by level <= rnd
order by dbms_random.value;
select mod(rownum,1000)+1 bulk collect into l_prod
from dual connect by level <= rnd+10
order by dbms_random.value;
select 'cat'||(mod(rownum,20)+1) bulk collect into l_cat
from dual connect by level <= rnd
order by dbms_random.value;
select mod(rownum,10)+1 bulk collect into l_item_cnt
from dual connect by level <= rnd
order by dbms_random.value;
end;
procedure run(p_seed int) is
begin
l_start := systimestamp;
for i in 1 .. iter
loop
idx := mod(iter,rnd)+1;
if mod(i,new_cust) = 0 then
new_customer('ssn'||(i*10+seed),'newname'||(i*10+seed),l_cust_id);
new_order(l_cust_id, l_order_id);
else
new_order(l_cust(idx), l_order_id);
end if;
for j in 1 .. mod(i,5)+1
loop
new_order_item(l_order_id, l_prod(idx+j), j, j );
end loop;
commit;
end loop;
update results
set tps = round(iter / extract(second from (systimestamp-l_start)),1),
ela = extract(second from (systimestamp-l_start))
where seed = p_seed;
commit;
end;
end;
/
pause
clear screen
conn ogb/ogb@YOURDB
lock table results in exclusive mode;
pause
--
-- the "sql_plus" below is just a batch file doing
--
-- @echo off
-- sqlplus.exe /nolog %1 %2 %3 %4 %5
-- exit
-- it just got complicated having all those commands nested in a "host start" on windows
--
host start sql_plus @ogb_bench.sql 0
host start sql_plus @ogb_bench.sql 1
host start sql_plus @ogb_bench.sql 2
host start sql_plus @ogb_bench.sql 3
host start sql_plus @ogb_bench.sql 4
host start sql_plus @ogb_bench.sql 5
REM
REM Nothing starts until I commit
REM
pause
commit;
REM
REM Waiting for benchmark to finish
REM
set echo off
declare
x int;
begin
loop
select count(*) into x
from results
where tps > 0;
exit when x = 6;
dbms_session.sleep(2);
end loop;
end;
/
pro
pro All completed!
pro
set echo on
clear screen
set echo off
set lines 200
col event format a44 TRUNC
col pct format a10
select min(ela), max(ela), avg(ela) from results where ela != 0;
select sum(tps) from results;
select * from
(
select EVENT
,TOTAL_WAITS
,TOTAL_TIMEOUTS
,SECS
,rpad(to_char(100 * ratio_to_report(secs) over (), 'FM00.00') || '%',8) pct
from (
select EVENT
,sum(TOTAL_WAITS) TOTAL_WAITS
,sum(TOTAL_TIMEOUTS) TOTAL_TIMEOUTS
,sum(TIME_WAITED/100) SECS
from v$session_event
where sid != sys_context('USERENV','SID')
and event not like 'SQL*Net%'
and event != 'enq: TM - contention'
and sid in ( select sid from v$session where username = 'OGB')
group by event
union all
select 'CPU', null, null, sum(value/100) from v$sesstat
where statistic# = ( select statistic# from v$statname where name = 'CPU used by this session')
and sid != sys_context('USERENV','SID')
and sid in ( select sid from v$session where username = 'OGB')
order by 4
))
where pct not like '00.00%';