![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
Colleagues, I'm trying to troubleshoot some performance issues pertaining to an SP. Despite setting/calling CALL SET_ROUTINE_OPTS(GET_ROUTINE_OPTS()||'EXPLAIN ALL'); SET CURRENT EXPLAIN MODE EXPLAIN; before executing the SP, none of the SQL associated with any of the cursor FOR loops within it is showing up in the EXPLAIN tables and therefore in db2exfmt. Note that all of the other (dynamic) SQL in the SP is explained. Here's a snippet of one of my cursor FOR loops, in case it helps: FOR L_DUP_IDS AS SELECT ID FROM SESSION.A_TABLE GROUP BY ID HAVING COUNT(REP) > 1 DO SET V_MAX_REP = (SELECT MAX(E.REP) FROM SESSION.A_TABLE E WHERE E._ID = L_DUP_IDS.ID);-- ... Anyone know how I can solve this? Since you are accessing a SESSION table you need to actually execute (drive) the procedure before you will see the plan. |
#3
| |||
| |||
|
|
jefftyzzer wrote: Colleagues, I'm trying to troubleshoot some performance issues pertaining to an SP. Despite setting/calling CALL SET_ROUTINE_OPTS(GET_ROUTINE_OPTS()||'EXPLAIN ALL'); SET CURRENT EXPLAIN MODE EXPLAIN; before executing the SP, none of the SQL associated with any of the cursor FOR loops within it is showing up in the EXPLAIN tables and therefore in db2exfmt. Note that all of the other (dynamic) SQL in the SP is explained. Here's a snippet of one of my cursor FOR loops, in case it helps: FOR L_DUP_IDS AS * * SELECT * * * * ID * * FROM * * * * SESSION.A_TABLE * * GROUP BY * * * * ID * * HAVING * * * * COUNT(REP) > 1 * * DO * * * * SET V_MAX_REP = (SELECT MAX(E.REP) FROM SESSION.A_TABLE E WHERE E._ID = L_DUP_IDS.ID);-- ... Anyone know how *I can solve this? Since you are accessing a SESSION table you need to actually execute (drive) the procedure before you will see the plan. SQL referring to SESSION temps doesn't get compiled until execution time. Cheers Serge -- Serge Rielau SQL Architect DB2 for LUW IBM Toronto Lab |
#4
| |||
| |||
|
|
On Jun 30, 6:33 pm, Serge Rielau <srie... (AT) ca (DOT) ibm.com> wrote: jefftyzzer wrote: Colleagues, I'm trying to troubleshoot some performance issues pertaining to an SP. Despite setting/calling CALL SET_ROUTINE_OPTS(GET_ROUTINE_OPTS()||'EXPLAIN ALL'); SET CURRENT EXPLAIN MODE EXPLAIN; before executing the SP, none of the SQL associated with any of the cursor FOR loops within it is showing up in the EXPLAIN tables and therefore in db2exfmt. Note that all of the other (dynamic) SQL in the SP is explained. Here's a snippet of one of my cursor FOR loops, in case it helps: FOR L_DUP_IDS AS SELECT ID FROM SESSION.A_TABLE GROUP BY ID HAVING COUNT(REP) > 1 DO SET V_MAX_REP = (SELECT MAX(E.REP) FROM SESSION.A_TABLE E WHERE E._ID = L_DUP_IDS.ID);-- ... Anyone know how I can solve this? Since you are accessing a SESSION table you need to actually execute (drive) the procedure before you will see the plan. SQL referring to SESSION temps doesn't get compiled until execution time. Cheers Serge -- Serge Rielau SQL Architect DB2 for LUW IBM Toronto Lab Thank you for your reply, Serge, but forgive me: what do you mean by "(drive) the procedure"? --Jeff CALL proc(); |
#5
| |||
| |||
|
|
jefftyzzer wrote: On Jun 30, 6:33 pm, Serge Rielau <srie... (AT) ca (DOT) ibm.com> wrote: jefftyzzer wrote: Colleagues, I'm trying to troubleshoot some performance issues pertaining to an SP. Despite setting/calling CALL SET_ROUTINE_OPTS(GET_ROUTINE_OPTS()||'EXPLAIN ALL'); SET CURRENT EXPLAIN MODE EXPLAIN; before executing the SP, none of the SQL associated with any of the cursor FOR loops within it is showing up in the EXPLAIN tables and therefore in db2exfmt. Note that all of the other (dynamic) SQL in the SP is explained. Here's a snippet of one of my cursor FOR loops, in case it helps: FOR L_DUP_IDS AS * * SELECT * * * * ID * * FROM * * * * SESSION.A_TABLE * * GROUP BY * * * * ID * * HAVING * * * * COUNT(REP) > 1 * * DO * * * * SET V_MAX_REP = (SELECT MAX(E.REP) FROM SESSION.A_TABLE E WHERE E._ID = L_DUP_IDS.ID);-- ... Anyone know how *I can solve this? Since you are accessing a SESSION table you need to actually execute (drive) the procedure before you will see the plan. SQL referring to SESSION temps doesn't get compiled until execution time. Cheers Serge -- Serge Rielau SQL Architect DB2 for LUW IBM Toronto Lab Thank you for your reply, Serge, but forgive me: what do you mean by "(drive) the procedure"? --Jeff CALL proc(); -- Serge Rielau SQL Architect DB2 for LUW IBM Toronto Lab |
#6
| |||
| |||
|
#7
| |||
| |||
|
|
For such a simple single row UPDATE? Absolutely reasonable. The compiler can easily dominate the cost for such a simple statement. I am somewhat surprised that you have REOPT ALWAYS as default. Also I think there is a lot of room to improve this code. One way would be to use a dynamic compound instead (that would require you do use dynamic SQL). Essentially te FOR LOOP and UPDATE stay the same, but you wrap it into a BEGIN ATOMIC block and EXECUTE [IMMEDIATE]. As a result the entire loop gets poured into a single plan and should execute much faster. -- Serge Rielau SQL Architect DB2 for LUW IBM Toronto Lab |
#8
| |||
| |||
|
|
On Jul 2, 5:02*pm, Serge Rielau <srie... (AT) ca (DOT) ibm.com> wrote: For such a simple single row UPDATE? Absolutely reasonable. The compiler can easily dominate the cost for such a simple statement. I am somewhat surprised that you have REOPT ALWAYS as default. Also I think there is a lot of room to improve this code. One way would be to use a dynamic compound instead (that would require you do use dynamic SQL). Essentially te FOR LOOP and UPDATE stay the same, but you wrap it into a BEGIN ATOMIC block and EXECUTE [IMMEDIATE].. As a result the entire loop gets poured into a single plan and should execute much faster. -- Serge Rielau SQL Architect DB2 for LUW IBM Toronto Lab Sorry--REOPT ONCE is the default, but when the package is instead rebound with ALWAYS, calamity ensues. As to your suggested improvement, I'm all ears. As I mentioned, the SQL I included here is just meant to facilitate discussion. If it's OK with you, I'd like to email you an example of the real SQL/PL, as I don't completely understand your recommendation. --Jeff |
#9
| |||
| |||
|
|
| 'FOR L_REPS AS ' | ' SELECT X, Y FROM Z ' | ' DO ' | ' UPDATE A SET C = N WHERE A.C = L_REPS.X; ' | ' UPDATE B SET C = N WHERE B.C = L_REPS.X; ' | ' UPDATE C SET C = N WHERE C.C = L_REPS.X; ' | ' UPDATE Z SET C = L_REPS.Y WHERE Z.C = L_REPS.X; ' | ' END FOR; END' |
#10
| |||
| |||
|
|
DECLARE txt VARCHAR(32000); SET txt = 'BEING ATOMIC ' || 'FOR L_REPS AS ' || ' SELECT X, Y FROM Z ' || ' DO ' || ' * *UPDATE A SET C = N WHERE A.C = L_REPS.X; ' || ' * *UPDATE B SET C = N WHERE B.C = L_REPS.X; ' || ' * *UPDATE C SET C = N WHERE C.C = L_REPS.X; ' || ' * *UPDATE Z SET C = L_REPS.Y WHERE Z.C = L_REPS.X; ' || ' END FOR; END' EXECUTE IMMEDIATE txt; If you EXPLAIN PLAN on this beats you should see a join between the FOR LOOP query and either a FILTER or a UNION operator where each arm is an UPDATE. Cheers Serge -- Serge Rielau SQL Architect DB2 for LUW IBM Toronto Lab |
![]() |
| Thread Tools | |
| Display Modes | |
| |