Quote:
|
Originally Posted by vini_srcna
Code:
OPEN 01390 00001 12810 63.09% 31.13% 00:00.283133 00:00.030186
FETCH 01550 00001 5431746 1.22% 5.24% 00:00.000013 00:00.000012
|
Apparently, the "open cursor" takes 63% of the program execution.
Not exceptional, I would say: it just means that the "real work" is done during "open cursor" and not during the subsequent fetches (since they only take 1% of the execution time).
This is always the case when "materialization" takes place: the full result set has to be generated (at "open" time) and stored by DB2 before the first line can be returned (by the first FETCH) because sorting is needed for a certain reason.
Quote:
|
Originally Posted by vini_srcna
Code:
DECLARE ERID_CURSOR CURSOR FOR
SELECT DISTINCT B.INV_ID
FROM ORG_STRUKTUR_S A
LEFT OUTER JOIN IP_IP_REL_S B
ON SUBSTR(A.IP_ID,1,10) = B.INV_ID_2
WHERE B.IR_KD = 'PRIMAER'
AND (CURRENT TIMESTAMP <= B.TIL_TS OR B.TIL_TS IS NULL)
AND A.OEST_NV = 'RAADGIV'
AND A.OEST_REL_TP IN ('DIREKTE','SAMLAGT','STAB')
AND A.IP_ID_2 = :USER_ID
|
The "DISTINCT" requires a sort, since that's the most efficient way to remove duplicates.
Remove the DISTINCT and the percentages will be totally different.
Certainly if your FETCH iteration does not continue until SQLCODE=100, materialization is suboptimal. But if you retrieve all rows from the result set, materialization might even be preferred, since it will e.g. release locks earlier (i.e., after the OPEN) than without materialization.
By removing the DISTINCT, the third line (METHOD=3) of explain output will disappear.
B.t.w., the JOIN condition (using SUBSTR) is potentially suboptimal ("stage-2" predicate); are you sure you need to substring to the first 10 positions? If the positions from 11 on are guaranteed to be blanks, you should better write "A.IP_ID = B.INV_ID_2".
Quote:
|
Originally Posted by vini_srcna
Code:
PLANNO METHOD TNAME ACCESSTYPE MATCHCOLS INDEXONLY
------ ------ ------------------ ---------- --------- ---------
1 0 ORG_STRUKTUR_S N 3 Y
2 1 IP_IP_REL_S I 1 N
3 3 0 N
|
The join is a nested one, i.e., the indexed access to table B is repeated for every matching row of table A. This need not be suboptimal, though; certainly not if the conditions on A (like A.IP_ID_2 = :USER_ID) are well filtering.