Je bent aardig stellig.... Puur ter vermaak loop ik je statement na (stukkie simpeler en vriendelijker naar de DBA)
Simpeler ligt er maar net aan waar je aan gewent bent. Persoonlijk vind ik ANSI-queries helemaal niet simpeler dan Oracle-dialect queries, dus voor mij is jouw query lastig (ergo: simpeler is niet meetbaar in deze).
Om je tweede uitspraak te controleren (vriendelijker naar de DBA) op juistheid heb ik een testje gemaakt in Oracle 11.2.0.2 op 64-bit Linux (draaiend in een VM op mijn laptop). Ik heb de gegevens die nu bekend zijn over de tabel verwerkt, een aantal kostenplaatsen en een paar jaar historie. Er zijn geen indexen aangemaakt, want er is op dit moment niets bekend over indexen of sleutels.
De test wordt tweemaal gedraaid: éénmaal met de data in cache en eenmaal zonder de data in cache. Ik denk dat het script verder voor zichzelf spreekt?
SQL:
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
| set echo on
conn/as sysdba
drop user demo cascade
/
create user demo identified by demo
default tablespace users
temporary tablespace temp
quota unlimited on users
/
/* Basic privs */
grant connect, resource to demo;
/* for trace */
grant alter session to demo;
/* for flush of shared_pool */
grant alter system to demo;
connect demo/demo
/* The table */
create table omzet
( jaar number(4) not null
, kostenplaats number(6) not null
, wtg1 number(10) default 10
, wtg2 number(10) default 10
, wtg3 number(10) default 10
, wtg4 number(10) default 10
, wtg5 number(10) default 10
, wtg6 number(10) default 10
, wtg7 number(10) default 10
, wtg8 number(10) default 10
, wtg9 number(10) default 10
, wtg10 number(10) default 10
, wtg11 number(10) default 10
, wtg12 number(10) default 10
)
/
/* Some data */
create sequence kostenplaats_seq
start with 1
/
begin
for i in 1..99999 loop
insert into omzet (jaar,kostenplaats) values (2010, kostenplaats_seq.nextval);
end loop;
insert into omzet (jaar, kostenplaats) ( select 2009, kostenplaats from omzet where jaar = 2010);
insert into omzet (jaar, kostenplaats) ( select 2008, kostenplaats from omzet where jaar = 2010);
insert into omzet (jaar, kostenplaats) ( select 2007, kostenplaats from omzet where jaar = 2010);
insert into omzet (jaar, kostenplaats) ( select 2006, kostenplaats from omzet where jaar = 2010);
insert into omzet (jaar, kostenplaats) ( select 2005, kostenplaats from omzet where jaar = 2010);
end;
/
/* statistics */
exec dbms_stats.gather_table_stats(ownname => 'DEMO', tabname => 'OMZET', cascade => TRUE);
/* First trace, without cache */
connect demo/demo
set termout off
alter session set sql_trace=true
/
/* clear caches */
alter system flush shared_pool;
alter system flush buffer_cache;
/* Curry */
select t1.kostenplaats, sum(t1.wtg1 + t1.wtg2 + t1.wtg3 + t1.wtg4 + t1.wtg5 + t1.wtg6 + t1.wtg7 + t1.wtg8 + t1.wtg9 + t2.wtg10 + t2.wtg11 + t2.wtg12)
from omzet t1
join omzet t2 ON t1.kostenplaats = t2.kostenplaats and t1.jaar=2010 and t2.jaar=2009
group by t1.kostenplaats
/
/* Clear caches */
alter system flush shared_pool;
alter system flush buffer_cache;
/* JaQ */
select t1.kostenplaats,
t1.som + t2.som
from ( select kostenplaats, sum(wtg1 + wtg2 + wtg3 + wtg4 + wtg5 + wtg6 + wtg7 + wtg8 + wtg9) as som
from omzet t1
where jaar = 2010
group by kostenplaats ) t1,
( select kostenplaats, sum(wtg10 + wtg11 + wtg12) as som
from omzet t1
where jaar = 2009
group by kostenplaats ) t2
where t1.kostenplaats = t2.kostenplaats
/
alter system set sql_trace=false
/
/* Second trace, with cache */
connect demo/demo
set termout off
alter system set sql_trace=true
/
/* Clear caches */
alter system flush shared_pool;
alter system flush buffer_cache;
/* load cache */
select *
from omzet
/
/* Curry */
select t1.kostenplaats, sum(t1.wtg1 + t1.wtg2 + t1.wtg3 + t1.wtg4 + t1.wtg5 + t1.wtg6 + t1.wtg7 + t1.wtg8 + t1.wtg9 + t2.wtg10 + t2.wtg11 + t2.wtg12)
from omzet t1
join omzet t2 ON t1.kostenplaats = t2.kostenplaats and t1.jaar=2010 and t2.jaar=2009
group by t1.kostenplaats
/
/* JaQ */
select t1.kostenplaats,
t1.som + t2.som
from ( select kostenplaats, sum(wtg1 + wtg2 + wtg3 + wtg4 + wtg5 + wtg6 + wtg7 + wtg8 + wtg9) as som
from omzet t1
where jaar = 2010
group by kostenplaats ) t1,
( select kostenplaats, sum(wtg10 + wtg11 + wtg12) as som
from omzet t1
where jaar = 2009
group by kostenplaats ) t2
where t1.kostenplaats = t2.kostenplaats
/
alter session set sql_trace = false
/
set termout on |
Nu de resultaten *insert tromgeroffel*
zonder cache:
code:
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
| select t1.kostenplaats, sum(t1.wtg1 + t1.wtg2 + t1.wtg3 + t1.wtg4 + t1.wtg5 + t1.wtg6 + t1.wtg7 + t1.wtg8 + t1.wtg9 + t2.wtg10 + t2.wtg11 + t2.wtg12)
from omzet t1
join omzet t2 ON t1.kostenplaats = t2.kostenplaats and t1.jaar=2010 and t2.jaar=2009
group by t1.kostenplaats
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 6668 0.45 0.57 4151 8312 0 99999
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6670 0.46 0.58 4151 8312 0 99999
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 99
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ---------------------------------------------------
99999 99999 99999 SORT GROUP BY NOSORT (cr=8312 pr=4151 pw=0 time=561332 us cost=3769 size=3591054 card=66501)
99999 99999 99999 MERGE JOIN (cr=8312 pr=4151 pw=0 time=507153 us cost=3769 size=7889886 card=146109)
99999 99999 99999 SORT JOIN (cr=4156 pr=4151 pw=0 time=249237 us cost=1692 size=1759968 card=97776)
99999 99999 99999 TABLE ACCESS FULL OMZET (cr=4156 pr=4151 pw=0 time=52081 us cost=1132 size=1759968 card=97776)
99999 99999 99999 SORT JOIN (cr=4156 pr=0 pw=0 time=133876 us cost=2077 size=3577464 card=99374)
99999 99999 99999 TABLE ACCESS FULL OMZET (cr=4156 pr=0 pw=0 time=20072 us cost=1132 size=3577464 card=99374)
********************************************************************************
select t1.kostenplaats,
t1.som + t2.som
from ( select kostenplaats, sum(wtg1 + wtg2 + wtg3 + wtg4 + wtg5 + wtg6 + wtg7 + wtg8 + wtg9) as som
from omzet t1
where jaar = 2010
group by kostenplaats ) t1,
( select kostenplaats, sum(wtg10 + wtg11 + wtg12) as som
from omzet t1
where jaar = 2009
group by kostenplaats ) t2
where t1.kostenplaats = t2.kostenplaats
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 6668 0.57 0.61 4151 8312 0 99999
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6670 0.57 0.62 4151 8312 0 99999
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 99
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ---------------------------------------------------
99999 99999 99999 HASH JOIN (cr=8312 pr=4151 pw=0 time=605556 us cost=3690 size=3423836 card=65843)
99999 99999 99999 VIEW (cr=4156 pr=4151 pw=0 time=274389 us cost=1574 size=1711918 card=65843)
99999 99999 99999 HASH GROUP BY (cr=4156 pr=4151 pw=0 time=257379 us cost=1574 size=1185174 card=65843)
99999 99999 99999 TABLE ACCESS FULL OMZET (cr=4156 pr=4151 pw=0 time=48724 us cost=1132 size=1759968 card=97776)
99999 99999 99999 VIEW (cr=4156 pr=0 pw=0 time=197430 us cost=1876 size=1729026 card=66501)
99999 99999 99999 HASH GROUP BY (cr=4156 pr=0 pw=0 time=175642 us cost=1876 size=2394036 card=66501)
99999 99999 99999 TABLE ACCESS FULL OMZET (cr=4156 pr=0 pw=0 time=63446 us cost=1132 size=3577464 card=99374)
******************************************************************************** |
Mijn query duurt een fractie langer dan jouw query, de "cost" is ook hoger. Tot zover heb je gelijk.
Met data in cache nogmaals de test:
code:
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
| select *
from omzet
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 40001 0.66 0.82 4151 43904 0 599994
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 40003 0.66 0.82 4151 43904 0 599994
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 99
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ---------------------------------------------------
599994 599994 599994 TABLE ACCESS FULL OMZET (cr=43904 pr=4151 pw=0 time=918676 us cost=1136 size=26999730 card=599994)
********************************************************************************
select t1.kostenplaats, sum(t1.wtg1 + t1.wtg2 + t1.wtg3 + t1.wtg4 + t1.wtg5 + t1.wtg6 + t1.wtg7 + t1.wtg8 + t1.wtg9 + t2.wtg10 + t2.wtg11 + t2.wtg12)
from omzet t1
join omzet t2 ON t1.kostenplaats = t2.kostenplaats and t1.jaar=2010 and t2.jaar=2009
group by t1.kostenplaats
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 6668 0.44 0.45 0 8312 0 99999
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6670 0.44 0.45 0 8312 0 99999
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 99
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ---------------------------------------------------
99999 99999 99999 SORT GROUP BY NOSORT (cr=8312 pr=0 pw=0 time=433074 us cost=3769 size=3591054 card=66501)
99999 99999 99999 MERGE JOIN (cr=8312 pr=0 pw=0 time=406903 us cost=3769 size=7889886 card=146109)
99999 99999 99999 SORT JOIN (cr=4156 pr=0 pw=0 time=132012 us cost=1692 size=1759968 card=97776)
99999 99999 99999 TABLE ACCESS FULL OMZET (cr=4156 pr=0 pw=0 time=25106 us cost=1132 size=1759968 card=97776)
99999 99999 99999 SORT JOIN (cr=4156 pr=0 pw=0 time=136224 us cost=2077 size=3577464 card=99374)
99999 99999 99999 TABLE ACCESS FULL OMZET (cr=4156 pr=0 pw=0 time=21569 us cost=1132 size=3577464 card=99374)
********************************************************************************
select t1.kostenplaats,
t1.som + t2.som
from ( select kostenplaats, sum(wtg1 + wtg2 + wtg3 + wtg4 + wtg5 + wtg6 + wtg7 + wtg8 + wtg9) as som
from omzet t1
where jaar = 2010
group by kostenplaats ) t1,
( select kostenplaats, sum(wtg10 + wtg11 + wtg12) as som
from omzet t1
where jaar = 2009
group by kostenplaats ) t2
where t1.kostenplaats = t2.kostenplaats
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 6668 0.37 0.40 0 8312 0 99999
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 6670 0.38 0.40 0 8312 0 99999
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 99
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ---------------------------------------------------
99999 99999 99999 HASH JOIN (cr=8312 pr=0 pw=0 time=385772 us cost=3690 size=3423836 card=65843)
99999 99999 99999 VIEW (cr=4156 pr=0 pw=0 time=127746 us cost=1574 size=1711918 card=65843)
99999 99999 99999 HASH GROUP BY (cr=4156 pr=0 pw=0 time=108690 us cost=1574 size=1185174 card=65843)
99999 99999 99999 TABLE ACCESS FULL OMZET (cr=4156 pr=0 pw=0 time=26408 us cost=1132 size=1759968 card=97776)
99999 99999 99999 VIEW (cr=4156 pr=0 pw=0 time=162913 us cost=1876 size=1729026 card=66501)
99999 99999 99999 HASH GROUP BY (cr=4156 pr=0 pw=0 time=139076 us cost=1876 size=2394036 card=66501)
99999 99999 99999 TABLE ACCESS FULL OMZET (cr=4156 pr=0 pw=0 time=27859 us cost=1132 size=3577464 card=99374)
******************************************************************************** |
Jouw query duurt nu plotsklaps langer en de cost is hoger. Bij herhaalde testen krijg ik vergelijkbare resultaten (waarbij ook nog valt op te merken dat de sort_join en merge_join veel meer temp gebruiken dan een hash_join en hash_group_by).
Conclusie: je statement "toch stukkie simpeler en vriendelijker naar de DBA" is bewezen onjuist. Je statement had moeten zijn "de ansi query is voor sommigen van ons eenvoudiger om te lezen en onder bepaalde voorwaarden sneller op de database.". En dan zeik ik nog niet over het incompleet zijn van je query
Wat heb jij hier verder aan: helemaal niets. Het was enkel een mooie gelegenheid voor mij om iemand (niet jij, iemand buiten GoT) uit te leggen hoe tracing werkt in Oracle en wat kleine valkuilen daarbij te tonen.