Home » SQL & PL/SQL » SQL & PL/SQL » To tune a PL/SQL block (12c, 11g )
To tune a PL/SQL block [message #639615] Sun, 12 July 2015 12:59 Go to next message
13478
Messages: 2
Registered: July 2015
Junior Member
Hello,

I have PL/SQL block, it runs, but runs slow,

The way to tune it, I think, may use BULK COLLECT.

while, after using BULK COLLECT (for cursor DOCUMENTS), got error:

Error report:
ORA-06550: line 375, column 39:
PLS-00497: cannot mix between single row and multi-row (BULK) in INTO list
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:

How could I fix it?
Is there any other way to tune this PL/SQL block?

thank you very much in advance!

original PL/SQL



* BlackSwan added {code} tags. Please do so yourself in the future. http://www.orafaq.com/forum/t/174502/
* LF applied [spoiler] tags

[Updated on: Sun, 12 July 2015 15:14] by Moderator

Report message to a moderator

Re: To tune a PL/SQL block [message #639616 is a reply to message #639615] Sun, 12 July 2015 13:06 Go to previous messageGo to next message
Michel Cadot
Messages: 68776
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator

This is unreadable. Do you really expect we count 375 lines to find the wrong one?

Please read OraFAQ Forum Guide and How to use [code] tags and make your code easier to read.
Also always post your Oracle version, with 4 decimals.

Use SQL*Plus and copy and paste your session, the WHOLE session (no image, no attachment, text inside the post and formatted as above explained).

Anyway, I think the message is clear "cannot mix between single row and multi-row (BULK) in INTO list".

Re: To tune a PL/SQL block [message #639617 is a reply to message #639615] Sun, 12 July 2015 14:10 Go to previous messageGo to next message
John Watson
Messages: 9003
Registered: January 2010
Location: Global Village
Senior Member
You expect someone to tune that???

Break it down: run the queries for each cursor, see how they run. Focus on the slow ones, and the ones executed many times.
btw, I think you are using UNION unnecessarily; UNION ALL will save some time.
Re: To tune a PL/SQL block [message #639618 is a reply to message #639617] Sun, 12 July 2015 14:21 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
ALTER SESSION SET SQL_TRACE=TRUE;

above produces a trace file which needs to be processed by "tkprof"
The resultant report will reveal SQL run times for every SQL statement that was traced/included.
Re: To tune a PL/SQL block [message #639619 is a reply to message #639618] Sun, 12 July 2015 15:35 Go to previous messageGo to next message
13478
Messages: 2
Registered: July 2015
Junior Member
thank you,

tkprof xxx_ora_xx.trc xxx_report.txt explain=system/xxx sys=no sort=exeela,prsela,fchela

find this sql, which took most of time...

SELECT L.UIDY, SUBSTR(L.PARN_OF_LINE_ID, INSTR(L.PARN_OF_LINE_ID, '&', 1, 3)
+ 1, ( INSTR(L.PARN_OF_LINE_ID, '&', 1, 4) - INSTR(L.PARN_OF_LINE_ID, '&',
1, 3) - 1 )), SUBSTR(L.PARN_OF_LINE_ID, INSTR(L.PARN_OF_LINE_ID, '&', 1, 4)
+ 1, ( INSTR(L.PARN_OF_LINE_ID, '&', 1, 5) - INSTR(L.PARN_OF_LINE_ID, '&',
1, 4) - 1 )), '0', TO_CHAR(L.LNUM), L.ACCD_TLNA, L.ACCD_FLNA, L.ACCD_LNAM,
INVD_TLNA, INVD_FLNA, INVD_LNAM, L.INVC_QY, L.ACCD_QY
FROM
MF_QO_ITMZ_LN L
WHERE L.UIDY IN (((SELECT REFD_LINE_ID FROM MF_VI_ITMZ_LN
WHERE SUBSTR(REFD_LINE_ID, INSTR(REFD_LINE_ID, '&', 1 , 4) + 1, (
INSTR(REFD_LINE_ID, '&', 1, 5) - INSTR(REFD_LINE_ID, '&', 1, 4) - 1 )) IN
(SELECT CD FROM MF_DOC_TYPE WHERE DTYP_CAT = ( 'QO' )) AND INVC_ACCR_FL =
'T') UNION (SELECT REFD_LINE_ID FROM MF_VI_ACTG_LN IV2 WHERE
SUBSTR(REFD_LINE_ID, INSTR(REFD_LINE_ID, '&', 1 , 4) + 1, (
INSTR(REFD_LINE_ID, '&', 1, 5) - INSTR(REFD_LINE_ID, '&', 1, 4) - 1 )) IN
(SELECT CD FROM MF_DOC_TYPE WHERE DTYP_CAT = ( 'QO' )) AND INVC_ACCR_FL =
'T') UNION (SELECT REFD_LINE_ID FROM MF_VI_ITMZ_LN IV2 WHERE
SUBSTR(REFD_LINE_ID, INSTR(REFD_LINE_ID, '&', 1 , 4) + 1, (
INSTR(REFD_LINE_ID, '&', 1, 5) - INSTR(REFD_LINE_ID, '&', 1, 4) - 1 )) IN
(SELECT CD FROM MF_DOC_TYPE WHERE DTYP_CAT = ( 'QO' )) AND INVC_ACCR_FL =
'T') UNION (SELECT REFD_LINE_ID FROM MF_TI_LN TI WHERE SUBSTR(REFD_LINE_ID,
INSTR(REFD_LINE_ID, '&', 1 , 4) + 1, ( INSTR(REFD_LINE_ID, '&', 1, 5) -
INSTR(REFD_LINE_ID, '&', 1, 4) - 1 )) IN (SELECT CD FROM MF_DOC_TYPE WHERE
DTYP_CAT = ( 'QO' )) AND INVC_ACCR_FL = 'T') UNION (SELECT REFD_LINE_ID
FROM MF_II_ACTG_LN II WHERE SUBSTR(REFD_LINE_ID, INSTR(REFD_LINE_ID, '&', 1
, 4) + 1, ( INSTR(REFD_LINE_ID, '&', 1, 5) - INSTR(REFD_LINE_ID, '&', 1, 4)
- 1 )) IN (SELECT CD FROM MF_DOC_TYPE WHERE DTYP_CAT = ( 'QO' )) AND
INVC_ACCR_FL = 'T') UNION (SELECT REFD_LINE_ID FROM MF_II_ITMZ_LN II WHERE
SUBSTR(REFD_LINE_ID, INSTR(REFD_LINE_ID, '&', 1 , 4) + 1, (
INSTR(REFD_LINE_ID, '&', 1, 5) - INSTR(REFD_LINE_ID, '&', 1, 4) - 1 )) IN
(SELECT CD FROM MF_DOC_TYPE WHERE DTYP_CAT = ( 'QO' )) AND INVC_ACCR_FL =
'T') UNION (SELECT REFD_LINE_ID FROM MF_II_HDAL II2 WHERE
SUBSTR(REFD_LINE_ID, INSTR(REFD_LINE_ID, '&', 1 , 4) + 1, (
INSTR(REFD_LINE_ID, '&', 1, 5) - INSTR(REFD_LINE_ID, '&', 1, 4) - 1 )) IN
(SELECT CD FROM MF_DOC_TYPE WHERE DTYP_CAT = ( 'QO' )) AND INVC_ACCR_FL =
'T')));


call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.02 0.03 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.02 0.02 0 11171 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.05 0.05 0 11171 0 1

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 117 xxx (recursive depth: 1)
Number of plan statistics captured: 1

it is explain is attached.

Ok, now sql tuning of this bad sql is the way to speed up this PL/SQL,hmmm... thinking how to tune this sql...


any suggestions are welcome.

thank you very much




Re: To tune a PL/SQL block [message #639620 is a reply to message #639619] Sun, 12 July 2015 15:49 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
>find this sql, which took most of time...
How do you say above when below shows it consumed only 0.05 seconds?
>total 4 0.05 0.05 0 11171 0 1
Re: To tune a PL/SQL block [message #639629 is a reply to message #639620] Mon, 13 July 2015 03:27 Go to previous message
cookiemonster
Messages: 13975
Registered: September 2008
Location: Rainy Manchester
Senior Member
You need to bulk collect into an array variable, not a record variable, that's why you're getting the error.
But it's a waste of time.
You've got code of the form:

OPEN cursor
LOOP
FETCH cursor INTO variables
EXIT WHEN cursor%NOTFOUND

other_variables := other_variables + cursor_variables;

END LOOP;


If you change the cursor (postings) to use SUM then you don't need to loop or do additions. The SQL will do all the calculations and you can get the results in a single fetch which should be faster.
Previous Topic: Variable in PLSQL
Next Topic: Select Query based on closed / reopened flag
Goto Forum:
  


Current Time: Mon Aug 10 05:59:35 CDT 2026