admin管理员组文章数量:1278984
I have this poorly performing DB2 query that is being executed +800000 daily. I know I can try an index to speed that up but Im wondering how I could possible get rid of this sub-select and use a join instead.
SELECT 1
INTO V_SELECT_ONE
FROM FB_POLICY
WHERE FB_POL_COUNTY || SUBSTR(CHAR(FB_POL_SERIAL),3,5) = IN_MEMBER_NUMBER
AND FB_POL_STATUS_CD = 'A'
AND (FB_POL_POLICY_NO, FB_POL_GROUP_NO, FB_POL_ACTIVITY_TS) IN
(SELECT FB_POL_POLICY_NO, FB_POL_GROUP_NO, MAX(FB_POL_ACTIVITY_TS)
FROM FB_POLICY
WHERE FB_POL_COUNTY || SUBSTR(CHAR(FB_POL_SERIAL),3,5) =
IN_MEMBER_NUMBER
AND NOT (SUBSTR(FB_POL_LOB,1,4) IN ('FBHP','LIFE')
AND FB_POL_EFFECTIVE_DT <= CURRENT DATE)
GROUP BY FB_POL_POLICY_NO, FB_POL_GROUP_NO
)
FETCH FIRST 1 ROWS ONLY;
Primary keys are PK is FB_POL_COUNTY, FB_POL_SERIAL, FB_POL_ACTIVITY_TS
I have this poorly performing DB2 query that is being executed +800000 daily. I know I can try an index to speed that up but Im wondering how I could possible get rid of this sub-select and use a join instead.
SELECT 1
INTO V_SELECT_ONE
FROM FB_POLICY
WHERE FB_POL_COUNTY || SUBSTR(CHAR(FB_POL_SERIAL),3,5) = IN_MEMBER_NUMBER
AND FB_POL_STATUS_CD = 'A'
AND (FB_POL_POLICY_NO, FB_POL_GROUP_NO, FB_POL_ACTIVITY_TS) IN
(SELECT FB_POL_POLICY_NO, FB_POL_GROUP_NO, MAX(FB_POL_ACTIVITY_TS)
FROM FB_POLICY
WHERE FB_POL_COUNTY || SUBSTR(CHAR(FB_POL_SERIAL),3,5) =
IN_MEMBER_NUMBER
AND NOT (SUBSTR(FB_POL_LOB,1,4) IN ('FBHP','LIFE')
AND FB_POL_EFFECTIVE_DT <= CURRENT DATE)
GROUP BY FB_POL_POLICY_NO, FB_POL_GROUP_NO
)
FETCH FIRST 1 ROWS ONLY;
Primary keys are PK is FB_POL_COUNTY, FB_POL_SERIAL, FB_POL_ACTIVITY_TS
Share Improve this question edited Feb 24 at 21:04 JDBA asked Feb 24 at 20:18 JDBAJDBA 8311 bronze badges 11 | Show 6 more comments3 Answers
Reset to default 0See this query example.
I hope this query is equivalent to your query.
It's easier to switch from it to JOIN.
SELECT 1
INTO V_SELECT_ONE
FROM FB_POLICY t1
WHERE FB_POL_COUNTY || SUBSTR(CHAR(FB_POL_SERIAL),3,5) = IN_MEMBER_NUMBER
AND FB_POL_STATUS_CD = 'A'
AND t1.FB_POL_ACTIVITY_TS=
(SELECT MAX(FB_POL_ACTIVITY_TS)
FROM FB_POLICY t2
WHERE t2.FB_POL_POLICY_NO=t1.FB_POL_POLICY_NO
and t2.FB_POL_GROUP_NO=t1.FB_POL_GROUP_NO
and t2.FB_POL_COUNTY=t1.FB_POL_COUNTY
and SUBSTR(CHAR(t2.FB_POL_SERIAL),3,5) = substr(char(IN_MEMBER_NUMBER),3,5)
AND NOT (SUBSTR(FB_POL_LOB,1,4) IN ('FBHP','LIFE')
AND FB_POL_EFFECTIVE_DT <= CURRENT DATE)
)
FETCH FIRST 1 ROWS ONLY;
I'm not specifically a DB2 expert, but from what I can tell, this is equivalent. I doubt it's faster, but it seems easier to read.
SELECT 1
INTO V_SELECT_ONE
FROM (
SELECT
FB_POL_POLICY_NO
, FB_POL_GROUP_NO
, FB_POL_ACTIVITY_TS
FROM FB_POLICY
WHERE FB_POL_COUNTY || SUBSTR(CHAR(FB_POL_SERIAL), 3, 5) = IN_MEMBER_NUMBER
AND FB_POL_STATUS_CD = 'A'
) A
INNER JOIN (
SELECT
FB_POL_POLICY_NO
, FB_POL_GROUP_NO
, MAX(FB_POL_ACTIVITY_TS) AS FB_POL_ACTIVITY_TS
FROM FB_POLICY
WHERE FB_POL_COUNTY || SUBSTR(CHAR(FB_POL_SERIAL), 3, 5) = IN_MEMBER_NUMBER
AND NOT (
SUBSTR(FB_POL_LOB, 1, 4) IN ('FBHP', 'LIFE')
AND FB_POL_EFFECTIVE_DT <= CURRENT DATE
)
GROUP BY
FB_POL_POLICY_NO
, FB_POL_GROUP_NO
) B ON B.FB_POL_POLICY_NO = A.FB_POL_POLICY_NO
AND B.FB_POL_GROUP_NO = A.FB_POL_GROUP_NO
AND B.FB_POL_ACTIVITY_TS = A.FB_POL_ACTIVITY_TS
FETCH FIRST 1 ROWS ONLY;
try not to use negative condition, like your: AND NOT (SUBSTR(FB_POL_LOB,1,4) IN ('FBHP','LIFE'). Try to use your query without this negative condition and add EXCEPT with same conditions plus AND (SUBSTR(FB_POL_LOB,1,4) IN ('FBHP','LIFE') -- without NOT.
本文标签: optimizationRemoving a subselect in SQL queryStack Overflow
版权声明:本文标题:optimization - Removing a sub-select in SQL query - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741243498a2364435.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
IN_MEMBER_NUMBER
- external parameter or table column? – ValNik Commented Feb 24 at 20:34FB_POL_POLICY_NO, FB_POL_GROUP_NO, FB_POL_ACTIVITY_TS
uniquely identify a row? If not then what does? – Charlieface Commented Feb 24 at 20:56