Hello: I need your kind assistance to debug an optimization issue. The following two select statements in my book are almost
identical. One does a lookup for security type ‘CFD’ and the other does the same lookup except for security ‘OP’.
When run with ‘CFD’ the query never returns. When run with ‘OP’ the results return almost
instantly. If I hard code ‘CFD’ to be 5 which is the
securitytypekey, the query runs instantly. The code for getsectypekey() is below. Please note SECURITYTYPE
contains only 28 rows. Why would these queries run so differently? Many thanks for taking the time to look at this issue. KD select sec.* from security sec , positions_gsco where positions_gsco.securitykey is NULL
and
upper(substring(productid,1,3)) = 'CFD' and
upper(positions_gsco.producttype) = 'OP' and
getsectypekey('CFD') = sec.securitytypekey and positions_gsco.taskrunkey
= 359 and
positions_gsco.issuecurrency = sec.securityissuecurrISO and
positions_gsco.strikeprice = sec.strikeprice and
positions_gsco.expirationdate = sec.expirationdate and (
positions_gsco.underlyingisin = sec.underlyingisin
or positions_gsco.underlyingcusip
= sec.underlyingcusip or
positions_gsco.underlyingbloombergticker = sec. underlyingbloomberg
) ; EXPLAIN "Nested " Join Filter: ((positions_gsco.issuecurrency =
(sec.securityissuecurriso)::bpchar) AND (positions_gsco.strikeprice =
sec.strikeprice) AND (positions_gsco.expirationdate = sec.expirationdate) AND
((positions_gsco.underlyingisin = (sec.underlyingisin)::bpchar) OR
(positions_gsco.underlyingcusip = (sec.underlyingcusip)::bpchar) OR
(positions_gsco.underlyingbloombergticker = sec.underlyingbloomberg)))" " -> Seq Scan on positions_gsco
(cost=0.00..2310.40 rows=1 width=72)" " Filter:
((securitykey IS NULL) AND (upper("substring"((productid)::text, 1,
3)) = 'CFD'::text) AND (upper((producttype)::text) = 'OP'::text) AND
(taskrunkey = 359))" " -> Seq Scan on "security"
sec (cost=0.00..504.52 rows=598 width=374)" " Filter:
(getsectypekey('CFD'::bpchar) = securitytypekey)" ** ** ** ** ** ** ** ** ** ** ** ** ** ** select sec.* from security sec , positions_gsco where positions_gsco.securitykey is NULL
and
upper(substring(productid,1,3)) != 'CFD'
and
upper(positions_gsco.producttype) = 'OP'
and
getsectypekey('OP') = sec.securitytypekey and
positions_gsco.taskrunkey = 359 and
positions_gsco.issuecurrency = sec.securityissuecurrISO and
positions_gsco.putcallind = sec.put_call and
positions_gsco.strikeprice = sec.strikeprice and
positions_gsco.expirationdate = sec.expirationdate and (
positions_gsco.underlyingisin = sec.underlyingisin
or
positions_gsco.underlyingcusip = sec.underlyingcusip or
positions_gsco.underlyingbloombergticker =
sec.underlyingbloomberg ) ; EXPLAIN "Hash Join (cost=514.99..2861.41 rows=1
width=374)" " Hash Cond: ((positions_gsco.issuecurrency =
(sec.securityissuecurriso)::bpchar) AND (positions_gsco.putcallind =
sec.put_call) AND (positions_gsco.expirationdate = sec.expirationdate))" " Join Filter: ((positions_gsco.strikeprice =
sec.strikeprice) AND ((positions_gsco.underlyingisin =
(sec.underlyingisin)::bpchar) OR (positions_gsco.underlyingcusip =
(sec.underlyingcusip)::bpchar) OR (positions_gsco.underlyingbloombergticker =
sec.underlyingbloomberg)))" " -> Seq Scan on positions_gsco
(cost=0.00..2310.40 rows=16 width=79)" " Filter:
((securitykey IS NULL) AND (upper("substring"((productid)::text, 1,
3)) <> 'CFD'::text) AND (upper((producttype)::text) = 'OP'::text) AND
(taskrunkey = 359))" " -> Hash (cost=504.52..504.52
rows=598 width=374)" " ->
Seq Scan on "security" sec (cost=0.00..504.52 rows=598
width=374)" "
Filter: (getsectypekey('OP'::bpchar) = securitytypekey)" ** ** ** ** ** ** ** ** ** ** ** ** ** ** CREATE OR REPLACE FUNCTION getsectypekey(sectype_in bpchar) RETURNS integer AS $BODY$ declare sectypekey integer; begin select securitytypekey into sectypekey from securitytype where position (upper('|' ||
sectype_in || '|' ) in upper(securitytypeaka) ) > 0; -- -- did not find a type above if sectypekey is NULL then select securitytypekey into sectypekey from securitytype where upper(securitytypeshort) =
'UNKNOWN'; end if; return sectypekey; end $BODY$ LANGUAGE 'plpgsql' VOLATILE; ALTER FUNCTION getsectypekey(sectype_in bpchar) OWNER TO
postgres; |