Long dynamic query not optimized ?
I have a stored procedure that dynamically builds a query string and then executes it.
I noticed that above certain number of WHERE conditions the query is much slower, even if the new conditions are always true (1=1).
Details:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
procedure findStuff(
p_a IN CHAR,
p_b IN CHAR,
p_c IN INTEGER,
p_d IN SMALLINT,
p_e IN VARCHAR2, -- and a few more parameters, omitted here...
p_out out sys_refcursor)
is
sqlQuery VARCHAR2(2024);
begin
sqlQuery := 'select T1.* from T1 ' ||
'where BAR1 = :c_false ';
IF p_a IS NOT NULL THEN
sqlQuery := sqlQuery || 'AND FOO_A=:p_a ';
ELSE
sqlQuery := sqlQuery || 'AND ((1=1) OR :p_a IS NULL) ';
END IF;
IF p_b IS NOT NULL THEN
sqlQuery := sqlQuery || 'AND FOO_B=:p_b ';
ELSE
sqlQuery := sqlQuery || 'AND ((1=1) OR :p_b IS NULL) ';
END IF;
IF p_c IS NOT NULL THEN
sqlQuery := sqlQuery || 'AND FOO_C=:p_c ';
ELSE
sqlQuery := sqlQuery || 'AND ((1=1) OR :p_c IS NULL) ';
END IF;
-- and a few more like that, for each input parameter...
-- c_false is a constant, defined in the package body
OPEN p_out FOR sqlQuery USING c_false, p_a, p_b, p_c, p_d,...;
end;The issue is, that this query takes about 0.34 seconds on my database, but if I remove two parameters (an IF block above) then it runs in 0.06 seconds.
Even if the corresponding parameter has the values NULL (so in efect I just removed a "AND ((1=1) OR NULL IS NULL) ".
Am I running into some limit here?
What are my options, besides removing some rarely used parameters from the procedure?
Is this some server setting (can it become an issue again later, even if I remove some conditions from the query) ?
Regard,
David
xerces8 wrote:
Am I running into some limit here?
What are my options, besides removing some rarely used parameters from the procedure?How many parameters are we talking about here in reality?
Either way you should check out the following: {message:id=9360003}
Also the approach you are taking is a pre-11.2. You should probably adopt the new approach that uses DBMS_SQL.TO_REFCURSOR function. Here is an (untested) example:
DECLARE
l_cursor NUMBER := DBMS_SQL.OPEN_CURSOR;
l_refcursor SYS_REFCURSOR;
l_sql VARCHAR2(250) := 'SELECT * FROM foo WHERE 1=1 ';
BEGIN
IF p_a IS NOT NULL THEN
l_sql := l_sql || ' AND p_a = :b_a';
END IF;
IF p_b IS NOT NULL THEN
l_sql := l_sql || ' AND p_b = :b_b';
END IF;
DBMS_SQL.PARSE(l_cursor, l_sql, DBMS_SQL.NATIVE);
IF p_a IS NOT NULL THEN
DBMS_SQL.BIND_VARIABLE(l_cursor,'b_a',p_a);
END IF;
IF p_b IS NOT NULL THEN
DBMS_SQL.BIND_VARIABLE(l_cursor,'b_b',p_b);
END IF;
DBMS_SQL.EXECUTE(l_cursor);
l_refcursor := DBMS_SQL.TO_REFCURSOR(l_cursor);
END;
/Edited by: Centinul on Jul 12, 2011 8:01 AM
Similar Messages
-
hi
im using a dynamic query to put in an internal table but its not working
Can you see whats wrong in that?
gv_query = ' au~uname AS OTCTUSERNM,'.
CONCATENATE gv_query 'a1object' '.' 'a1field' ' AS 0TCTAUTH' INTO gv_query.
CONCATENATE gv_query 'au~to_dat AS OTCTADTO, OTCTOBJNM, ' INTO gv_query.
SELECT DISTINCT (gv_query)
INTO CORRESPONDING FIELDS OF TABLE gi_ds1
FROM agr_users AS au INNER JOIN
agr_1251 AS a1
ON auagr_name = a1agr_name.Hello,
Following are the observations:
1. gv_query = ' au~uname AS OTCTUSERNM,'.
>> In above string i think you want to use uname column as OTCTUSERNM and it is correct
2. CONCATENATE gv_query 'a1object' '.' 'a1field' ' AS 0TCTAUTH' INTO
gv_query.
>> In statement 2 above I am not able to understand whey 'a1object' '.' 'a1field' this is incorrect.
Also '.' (dot) in not required in query it will be either '~' or 'AS' as valid chars.
3. CONCATENATE gv_query 'au~to_dat AS OTCTADTO, OTCTOBJNM, ' INTO gv_query.
>> In statement 3 above whey OTCTOBJNM is used there is no such column exit in AGR_USERS.
4. SELECT DISTINCT (gv_query)
INTO CORRESPONDING FIELDS OF TABLE gi_ds1
FROM agr_users AS au INNER JOIN
agr_1251 AS a1
ON auagr_name = a1agr_name.
>> In above statement a1 is used as alias for AGR_USERS then why it it not there in statement 3 where instead au is used.
Normarlly query is like this
'<alias1><col_name1> as <col_desc1>, <alias2><col_name2> as <col_desc2>......up to n cols
In this case it is possible that alias1 and alias2 are used for different table in case of joins and for same table in case of self joins.
Finally, You can only define colums in dynamic query those are available in the table from which we have to select the data.
Hope this helps.
Thanks,
Augustin. -
My iPhone 4 no longer connects to my car or alarm clock after a recent sync to my computer. The message at I get when trying to. Connect is "this accessory is not optimized for the device" or something like that. Anyone know how to fix this?
Hello there philp_69,
If I understand correctly it sounds like your phone hasnt been recognized in iTunes on your PC since the last couple of updates. I would use the troubleshooting in the following article which will walk you through the steps one by one.
iPhone, iPad, or iPod touch not recognized in iTunes for Windows
Thank you for using Apple Support Communities.
All the very best,
Sterling -
Hello All,
We are using a two tier architecture.
Our Corp server calls the refinery server.
Our CORP MII server uses user id abc_user to connect to the refinery data server.
The user id abc_user has the SAP_xMII_Dynamic_Query role.
The data server also has the checkbox for allow dynamic query enabled.
But we are still getting the following error
Error has occurred while processing data stream
Dynamic Query role is not assigned to the Data Server; Use query template
Once we add the SAP_xMII_Dynamic_Query role to the data server everything works fine. Is this feature by design ?
Thanks,
KiranThanks Anushree !!
I thought that just adding the role to the user and enabling the dynamic query checkbox on the data server should work.
But we even needed to add the role to the data server.
Thanks,
Kiran -
BUG? ORA-01461 in Unit Tester when saving a long Dynamic Value Query
I get an ORA-01461 "can bind a LONG value only for insert into a LONG column" error when saving a Test Implementation with a Dynamic Value Query whose length of the SQL statement is roughly 2,000 characters - I'm UNIONing ALL about 30 test case values together, but it seems to be choking on such a long SQL string for some reason....
I am running version Early Adopter Release #2 (2.1.0.63), build MAIN-63.10.
Thoughts?Confirmed.
Bug 9119144: ORA-01461 IN UNIT TESTER WHEN SAVING A LONG DYNAMIC VALUE QUERY (OR OTHER CLOB)
Brian Jeffries
SQL Developer Team -
hi ,
i am using oracle 10g
i have created as view that has few 100 Ks of records -- long_view
and i have a table with few 100s of records -- small_table
the performance if the long_view is good i.e records are returned fast even though from explain plan , it uses "table access full" for some tables
however , when i join the view to the table , the performance is slow
select distinct a.name from long_view a , small_table b
where a.name = b.namebase tables used by the views have been analyzed
what does this indicate ? my view is not optimal ?
what i dun understand is how come the view by itself is fast but not when linked to another table ?
pls advise
tks & rgdshi ,
1 - my measurement of the performance of the view is it returns records fast and i stopped when it reached close to 100k and it's within a minute
2 here's the explain plan , (i need to dig out how i got the execution plan using tkprof, will take some time)
-- join of view & table
SELECT STATEMENT, GOAL = ALL_ROWS Cost=5576 Cardinality=1 Bytes=150
HASH UNIQUE Cost=5576 Cardinality=1 Bytes=150
HASH JOIN OUTER Cost=5575 Cardinality=1 Bytes=150
NESTED LOOPS OUTER Cost=5506 Cardinality=1 Bytes=142
NESTED LOOPS OUTER Cost=5506 Cardinality=1 Bytes=132
NESTED LOOPS Cost=1872 Cardinality=1 Bytes=119
HASH JOIN Cost=1870 Cardinality=2 Bytes=198
MAT_VIEW ACCESS BY INDEX ROWID Object owner=DA Object name=PI Cost=835 Cardinality=4 Bytes=248
NESTED LOOPS Cost=1672 Cardinality=8 Bytes=608
TABLE ACCESS FULL Object owner=DA Object name=PC Cost=3 Cardinality=2 Bytes=28
INDEX RANGE SCAN Object owner=DA Object name=PI_IDX1 Cost=831 Cardinality=4
MAT_VIEW ACCESS FULL Object owner=DA Object name=PR Cost=198 Cardinality=11170 Bytes=256910
INDEX RANGE SCAN Object owner=DA Object name=GE_IDX1 Cost=1 Cardinality=1 Bytes=20
VIEW PUSHED PREDICATE Object owner=DA Cost=3633 Cardinality=1 Bytes=13
HASH JOIN Cost=3633 Cardinality=19 Bytes=1463
INLIST ITERATOR
MAT_VIEW ACCESS BY INDEX ROWID Object owner=DA Object name=PI Cost=3436 Cardinality=19 Bytes=1064
INDEX RANGE SCAN Object owner=DA Object name=PI_IDX1 Cost=3420 Cardinality=19
MAT_VIEW ACCESS FULL Object owner=DA Object name=PR Cost=196 Cardinality=22341 Bytes=469161
INDEX UNIQUE SCAN Object owner=DA Object name=PST_PK Cost=0 Cardinality=1 Bytes=10
MAT_VIEW ACCESS FULL Object owner=DA Object name=RCP Cost=69 Cardinality=9623 Bytes=76984
-- select * from view itself
SELECT STATEMENT, GOAL = ALL_ROWS Cost=8540 Cardinality=10033 Bytes=20256627
VIEW Object owner=DA Object name=PR_CURR_RVIEW Cost=8540 Cardinality=10033 Bytes=20256627
WINDOW SORT Cost=8540 Cardinality=10033 Bytes=3832606
HASH JOIN RIGHT OUTER Cost=7719 Cardinality=10033 Bytes=3832606
MAT_VIEW ACCESS FULL Object owner=DA Object name=RCP Cost=69 Cardinality=9623 Bytes=740971
HASH JOIN OUTER Cost=7649 Cardinality=8203 Bytes=2501915
HASH JOIN OUTER Cost=3827 Cardinality=832 Bytes=152256
HASH JOIN Cost=3811 Cardinality=832 Bytes=128960
MAT_VIEW ACCESS FULL Object owner=DA Object name=GE Cost=15 Cardinality=776 Bytes=31816
HASH JOIN Cost=3795 Cardinality=30711 Bytes=3501054
MAT_VIEW ACCESS FULL Object owner=DA Object name=PR Cost=198 Cardinality=11170 Bytes=502650
MAT_VIEW ACCESS FULL Object owner=DA Object name=PI Cost=3595 Cardinality=110814 Bytes=7646166
MAT_VIEW ACCESS FULL Object owner=DA Object name=PST Cost=15 Cardinality=3653 Bytes=102284
VIEW Object owner=DA Cost=3818 Cardinality=287470 Bytes=35071340
HASH JOIN Cost=3818 Cardinality=287470 Bytes=21272780
MAT_VIEW ACCESS FULL Object owner=DA Object name=PR Cost=196 Cardinality=22341 Bytes=469161
MAT_VIEW ACCESS FULL Object owner=DA Object name=PI Cost=3613 Cardinality=554069 Bytes=29365657pls advise -
Closing/Killing a long runing Query gracefully using PLSQL
I have dynamic query which I want to kill programatically in PLSQL if its runing for more then 5 mins and return NULL result set.
Any advise how best in can do it.
I read about dbms_alert but not sure that is the correct way.
Any inputs on this
Thanks
RaviIf that Oracle session is tied to a client application, then there is a 3rd option.
The OCI (Oracle Call Interface) allows the client to make an "interrupt session's execution" call. This will terminate the current execution, but not the session itself. SQL*Plus for example uses this when you press CTRL-BREAK while a stored proc or SQL call is being executed by the server.
The real issue though is Why? It is not the usual approach to "abort" a long running process.
If the process does not complete in 5 minutes now, there is absolutely no guarantees that it will be able to do so when executed again. So that makes the execution on that process senseless... and the actions executed by that process meaningless.
I would rather address that process and actions then deal with the symptoms by forcing it to terminate after 5 minutes. -
How to dynamically query oracle from SAPGUI
hi all,
there are so many facilities available in SAPGUI to query the database for checking it status etc etc. but these queries i guess are based on the last database check done using db13. if it is true can any body tell me how can i dynamically query the database as and when required. eg to check the status of the datafile etc.
if i check the "space statistics" in db02 is is based on the db13 database check. "refresh" is not feasible as it takes much longer time and puts load on produciton system.
regards
AijazYou could do a cost analysis on a SQL Statement to get to a screen where you can put in a straight SQL Statement (I think ST04 can get you there somehow, I don't know, I've move from Basis to BI, so I can't check to confirm if that's the right transaction). But I don't know if it will allow you access to non-schema owned tables such as dba_data_files.
Your best bet would be to have your Oracle DBA or OS or Basis group write a simple SQL query that is triggered at the OS level via sqlplus and maybe tie it to a command you could run ad-hoc via immediate job execution. -
Dynamic Query and default run-time values
I am trying to build a dynamic query within dreamweaver and
retain access from the bindings panel.
here is a simple pseudo-query I want to expand on.
"SELECT object FROM objects_table WHERE widget_number =
widgets"
widgets is set up as a variable with a run-time value that
relates to $_GET['widgets']
this works fine but now i want to expand on this so the query
returns all results if $_GET['widgets'] is undefined. I was hoping
I could set the default value for widgets to equal widget_number so
I would get....
"SELECT object FROM objects_table WHERE widget_number =
widget_number" but the runtime query is actually
"SELECT object FROM objects_table WHERE widget_number =
'widget_number' " which obviously doesn't work.
I can alter the query manually from the code view but then I
lose access to the bindings panel as dreamweaver doesn't parse the
query properly.
Any pointers?
Thanks in advance
- AndrewAndy Millne wrote:
> That will work fine server-side yeah but dreamweaver
cannot parse the code at
> design time so by altering the code in this way you lose
access to the bindings
> panel and all the server behaviours that depend on the
recordset have
> exclamation marks alongside.
This is simply a question of organizing your workflow. As you
have
discovered, Dreamweaver no longer recognizes a recordset if
you make
changes to the basic structure of the code. The answer is to
use
Dreamweaver to construct your page using an unaltered
recordset. Once
the design stage is complete, make the changes required by
inserting
your conditional statement. Yes, the fieldnames disappear
from the
Bindings panel, and you get exclamation marks in the Server
Behaviors
panel, but that's not important. If you need to restore them
for any
reason, just wrap the changes in /* */ comments. Remove the
comments
when you have finished.
David Powers, Adobe Community Expert
Author, "The Essential Guide to Dreamweaver CS3" (friends of
ED)
Author, "PHP Solutions" (friends of ED)
http://foundationphp.com/ -
Greetings. My ultimate goal is to be able to type in an account number in a browser enabled InfoPath form textbox and have it retrieve information about that account (customer's name, address, etc.). I've set up an External content type
to a SQL table with 100,000+ rows and created the external list to hold the data (after disabling the throttling limits). I set a filter when creating the ECT and can't filter the data any more for my purposes. I increased the data
connection timeouts and response sizes in InfoPath just to see how long it would take to retrieve this data in InfoPath so that I could use a form to interface and query the data. The performance of the form is unacceptable to me as it took nearly 7
minutes to load. So, my question: are there alternatives to custom code that will work for my situation? Can I somehow dynamically set the content type filter through an InfoPath field so that I need not query all 100,000 records? I
know I can dynamically adjust a querystring directly to SQL through C# or VB but I'm trying to avoid that because I want to publish my form as a site content type (as opposed to an administrator approved form template).
Thanks in advance.
Andy
Hi,
According to your post, my understanding is that you wanted to dynamic query from Infopath.
I recommend to add code to the "click" event of a button to modify a SQL Server secondary data connection to use a "filter" from your form.
Here is a similar thread for your reference:
http://social.technet.microsoft.com/Forums/en-US/5aa4519c-b8e0-4a7c-85b4-09f7e1d0747a/dynamic-sql-data-connection-in-infopath?forum=sharepointcustomizationprevious
Best Regards,
Linda Li
Linda Li
TechNet Community Support -
Help on performance with dynamic query
Hi All,
We are using SQL Server 2008R2. In our one of report we are using Dynamic query and it is taking more time to retrieve the data. to retrieve 32 records it is taking 13-15 secs. In my observation in a table variable, created more than 60 columns. In
the SP called one more sp with insert statement.
Please let me know how i can improve performance of the SP.
I know that i have to provide the SP for observation but unfortunately I cannot provide the SP. Please guide me how i can achieve this .
I tried with temp tables by creating indexes on temp tables but i couldn't find improvement in performance.
Waiting for valuable replies.First of all a "dynamic query" is not "a query" - it is a multitude of them. Some of them may be fast, others may be slow.
There is of course no way we can give specific suggestions without seeing the code, the table and index definitions etc.
We can only give the generic suggestions. As for the code, make sure that you are using parameterised SQL and you are not building a complete SQL string with parameters and all. If nothing else, this helps to make the code more readable and maintainable.
It also protects you against SQL injection. And it also helps to prevent performance issue due to implicit conversion.
You will need to look at the query plan to see where the bottlenecks may be. You should look at the actual query plan. Note that the thickness of the arrows are more relevant than the percentages you see; the percentages are only estimates, and estimates
are often off. Next step is to see if you can add indexes to alleviate the situation. You should also analyse if there are problems in the query, for instance indexed columns that are entangled in expression. If you are using views, make sure that you don't
have views built on top of views etc. This can often result a table appearing multiple times in a query, when one would be enough.
Erland Sommarskog, SQL Server MVP, [email protected] -
How to find table name(s) in a dynamic query
In one of our (9iAS PORTAL)applications, any user can able to run their query statment and get output. All queries will be executed as dynamic SQL thru' a common shema/user who has 'SELECT' privilege on all tables but all users don't have this privilege on all tables. Now, before executing any query I need to find out what are the table name(s) used in this query to check the privilege for the respective user. How do I extract all table names being used in a dynamic query?.
Thanks
-KrishnamurthyI guess that his users log in to application first, then application uses one account to log in to database, so application are not direct database user since all users share the same account to database. If so, when a user lgins in, you may write it down from application to a database audit table, and you need to write down the dynamic query to the database audit table too, then you may query that audit table to find out. up to here, it looks that your application has to do more to assign what role to a user running the application, since database does not know what user is assessing it.
-
Hi all;
Can u please help me on the following dynamic query code ? I know I am missing the single quote around 2 dates but could not figure out where to put it ! I have tried putting 2 or 3 quotes around 2 bind vars but to no avail.
Want to create a dynamic query to simulate the the following:
select
EMPNO,ENAME,JOB,MGR,HIREDATE from emp where HIREDATE >= to_date('01/01/1981','MM/DD/YYYY') and HIREDATE <= to_date('12/31/1982','MM/DD/YYYY');
dynamic code:
declare
v_q varchar2(4000);
begin
v_q :='select EMPNO,ENAME,JOB,MGR,HIREDATE from emp ';
V_q := V_Q
|| 'where HIREDATE >= '
|| 'to_date(' || :P_DATE1 || ',' ||'''MM/DD/YYYY''' || ' )'
|| 'and HIREDATE <= '
|| 'to_date(' || :P_DATE2 || ',' ||'''MM/DD/YYYY''' || ' )';
-- end the sql
v_q := v_q ||';';
dbms_output.put_line ('V_Q is ' || V_Q);
end;
Thanks.
Zendeclare
v_q varchar2(4000);
v_rec emp%rowtype;
v_cur sys_refcursor;
begin
v_q :='select EMPNO,ENAME,JOB,MGR,HIREDATE from emp ';
V_q := V_Q || 'where HIREDATE >= to_date(:P_DATE1,''MM/DD/YYYY'') and HIREDATE <= to_date(:P_DATE2,''MM/DD/YYYY'')';
dbms_output.put_line ('V_Q is ' || V_Q);
open v_cur
for v_q
using '01/01/1981',
'12/31/1982';
loop
fetch v_cur
into v_rec.empno,
v_rec.ename,
v_rec.job,
v_rec.mgr,
v_rec.hiredate;
exit when v_cur%notfound;
dbms_output.put_line('empno = ' || v_rec.empno);
dbms_output.put_line('ename = ' || v_rec.ename);
dbms_output.put_line('job = ' || v_rec.job);
dbms_output.put_line('mgr = ' || v_rec.mgr);
dbms_output.put_line('hiredate = ' || to_char(v_rec.hiredate,'MM/DD/YYYY'));
dbms_output.put_line('====================');
end loop;
close v_cur;
end;
V_Q is select EMPNO,ENAME,JOB,MGR,HIREDATE from emp where HIREDATE >=
to_date(:P_DATE1,'MM/DD/YYYY') and HIREDATE <= to_date(:P_DATE2,'MM/DD/YYYY')
empno = 7499
ename = ALLEN
job = SALESMAN
mgr = 7698
hiredate = 02/20/1981
====================
empno = 7521
ename = WARD
job = SALESMAN
mgr = 7698
hiredate = 02/22/1981
====================
empno = 7566
ename = JONES
job = MANAGER
mgr = 7839
hiredate = 04/02/1981
====================
empno = 7654
ename = MARTIN
job = SALESMAN
mgr = 7698
hiredate = 09/28/1981
====================
empno = 7698
ename = BLAKE
job = MANAGER
mgr = 7839
hiredate = 05/01/1981
====================
empno = 7782
ename = CLARK
job = MANAGER
mgr = 7839
hiredate = 06/09/1981
====================
empno = 7839
ename = KING
job = PRESIDENT
mgr =
hiredate = 11/17/1981
====================
empno = 7844
ename = TURNER
job = SALESMAN
mgr = 7698
hiredate = 09/08/1981
====================
empno = 7900
ename = JAMES
job = CLERK
mgr = 7698
hiredate = 12/03/1981
====================
empno = 7902
ename = FORD
job = ANALYST
mgr = 7566
hiredate = 12/03/1981
====================
empno = 7934
ename = MILLER
job = CLERK
mgr = 7782
hiredate = 01/23/1982
====================
PL/SQL procedure successfully completed.
SQL> SY. -
Long running query--- included steps given by Randolf
Hi,
I have done my best to follow Randolf instruction word-by-word and hope to get solution for my
problem soon. Sometime back I have posted a thread on this problem then got busy with other
stuff and was not able to follow it. Here I am again with same issue.
here is link for my previous post
long running query in database 10gHere is backgroud of my requriemment.
I am working on Oracle forms 10g which is using package given below. We want to display client information
with order count basd on different status like Pending, Error, back Order, expedited, std shipping.
Output will look something like.
client name pending error backorder expedited std shipping
ABC 24 0 674 6789 78900
XYZ 35 673 5700 0 798274
.There are total 40 clients . The long running query are expedited and std shipping.
When i run package from Oracle Form Developer it takes 3 mintues to run but when I run same query in our application using forms
(which uses Oracle Application Server) it takes around 1 hour, which is completly unacceptable.
User wants it be done in less than 1 mintue.
I have tried combining Pending,error and backorder queries together but as far as I know it will not
work in Oracle Form as we need a place holder for each status.
Please dont think it is Forms related question, it is a Performance problem.
PACKAGE BODY ORDER_COUNT_PKG IS
PROCEDURE post_query IS
BEGIN
BEGIN
SELECT count(*)
INTO :ORDER_STATUS.PENDING
FROM orders o
WHERE o.status = 'P'
AND (parent_order_id is null
OR (order_type='G'
AND parent_order_id=original_order_number))
AND o.client = :ORDER_STATUS.CLIENT_NUMBER;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
BEGIN
SELECT count(*)
INTO :ORDER_STATUS.ERROR
FROM orders o
WHERE o.status = 'E'
AND (parent_order_id is null
OR (order_type='G'
AND parent_order_id=original_order_number))
AND o.client = :ORDER_STATUS.CLIENT_NUMBER;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
BEGIN
SELECT count(*)
INTO :ORDER_STATUS.BACK_ORDER
FROM orders o
WHERE o.status = 'B'
AND (parent_order_id is null
OR (order_type='G'
AND parent_order_id=original_order_number))
AND o.client = :ORDER_STATUS.CLIENT_NUMBER;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
BEGIN
SELECT count(*)
INTO :ORDER_STATUS.EXPEDITE
FROM orders o,shipment_type_methods stm
WHERE o.status in ('A','U')
AND (o.parent_order_id is null
OR (o.order_type = 'G'
AND o.parent_order_id = o.original_order_number))
AND o.client = stm.client
AND o.shipment_class_code = stm.shipment_class_code
AND (nvl(o.priority,'1') = '2'
OR stm.surcharge_amount <> 0)
AND o.client = :ORDER_STATUS.CLIENT_NUMBER
GROUP BY o.client;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
BEGIN
SELECT count(*)
INTO :ORDER_STATUS.STD_SHIP
FROM orders o,shipment_type_methods stm
WHERE o.status in ('A','U')
AND (o.parent_order_id is null
OR (o.order_type = 'G'
AND o.parent_order_id = o.original_order_number))
AND nvl(o.priority,'1') <> '2'
AND o.client = stm.client
AND o.shipment_class_code = stm.shipment_class_code
AND stm.surcharge_amount = 0
AND o.client = :ORDER_STATUS.CLIENT_NUMBER
GROUP BY o.client;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END post_query;
END ORDER_COUNT_PKG;one of the query which is taking long time is
SELECT count(*)
FROM orders o,shipment_type_methods stm
WHERE o.status in ('A','U')
AND (o.parent_order_id is null
OR (o.order_type = 'G'
AND o.parent_order_id = o.original_order_number))
AND nvl(o.priority,'1') <> '2'
AND o.client = stm.client
AND o.shipment_class_code = stm.shipment_class_code
AND stm.surcharge_amount = 0
AND o.client = :CLIENT_NUMBER
GROUP BY o.clientThe version of the database is 10.2.1.0.2
SQL> alter session force parallel dml;These are the parameters relevant to the optimizer:
SQL> show parameter user_dump_dest
NAME TYPE VALUE
user_dump_dest string /u01/app/oracle/admin/mcgemqa/
udump
SQL> show parameter optimizer
NAME TYPE VALUE
optimizer_dynamic_sampling integer 2
optimizer_features_enable string 10.2.0.4
optimizer_index_caching integer 0
optimizer_index_cost_adj integer 100
optimizer_mode string ALL_ROWS
optimizer_secure_view_merging boolean TRUE
SQL> show parameter db_file_multi
NAME TYPE VALUE
db_file_multiblock_read_count integer 16
SQL> show parameter db_block_size
NAME TYPE VALUE
db_block_size integer 8192
SQL> show parameter cursor_sharing
NAME TYPE VALUE
cursor_sharing string EXACTHere is the output of EXPLAIN PLAN:
SQL> explain plan for
2 SELECT count(*)
3 FROM orders o,shipment_type_methods stm
4 WHERE o.status in ('A','U')
5 AND (o.parent_order_id is null
6 OR (o.order_type = 'G'
7 AND o.parent_order_id = o.original_order_number))
8 AND nvl(o.priority,'1') <> '2'
9 AND o.client = stm.client
10 AND o.shipment_class_code = stm.shipment_class_code
11 AND stm.surcharge_amount = 0
12 AND o.client = :CLIENT_NUMBER
13 GROUP BY o.client
14 /
Explained.
Elapsed: 00:00:00.12
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 559278019
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 35 | 46764 (3)| 00:09:22 |
| 1 | SORT GROUP BY NOSORT | | 1 | 35 | 46764 (3)| 00:09:22 |
|* 2 | TABLE ACCESS BY INDEX ROWID | ORDERS | 175K| 3431K| 25979 (3)| 00:05:12 |
| 3 | NESTED LOOPS | | 25300 | 864K| 46764 (3)| 00:09:22 |
|* 4 | TABLE ACCESS BY INDEX ROWID| SHIPMENT_TYPE_METHODS | 1 | 15 | 2 (0)| 00:00
|* 5 | INDEX RANGE SCAN | U_SHIPMENT_TYPE_METHODS | 2 | | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | ORDERS_ORDER_DATE | 176K| | 2371 (8)| 00:00:29 |
Predicate Information (identified by operation id):
2 - filter(("O"."PARENT_ORDER_ID" IS NULL OR "O"."ORDER_TYPE"='G' AND
"O"."PARENT_ORDER_ID"=TO_NUMBER("O"."ORIGINAL_ORDER_NUMBER")) AND NVL("O"."PRIORITY",'1')<>'2
AND "O"."SHIPMENT_CLASS_CODE"="STM"."SHIPMENT_CLASS_CODE")
4 - filter("STM"."SURCHARGE_AMOUNT"=0)
5 - access("STM"."CLIENT"=:CLIENT_NUMBER)
6 - access("O"."CLIENT"=:CLIENT_NUMBER)
filter("O"."STATUS"='A' OR "O"."STATUS"='U')
24 rows selected.
Elapsed: 00:00:00.86
SQL> rollback;
Rollback complete.
Elapsed: 00:00:00.07Here is the output of SQL*Plus AUTOTRACE including the TIMING information:
SQL> SELECT count(*)
2 FROM orders o,shipment_type_methods stm
3 WHERE o.status in ('A','U')
4 AND (o.parent_order_id is null
5 OR (o.order_type = 'G'
6 AND o.parent_order_id = o.original_order_number))
7 AND nvl(o.priority,'1') <> '2'
8 AND o.client = stm.client
9 AND o.shipment_class_code = stm.shipment_class_code
10 AND stm.surcharge_amount = 0
11 AND o.client = :CLIENT_NUMBER
12 GROUP BY o.client
13 /
Elapsed: 00:00:03.09
Execution Plan
Plan hash value: 559278019
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 35 | 46764 (3)| 00:09:22 |
| 1 | SORT GROUP BY NOSORT | | 1 | 35 | 46764 (3)| 00:09:22 |
|* 2 | TABLE ACCESS BY INDEX ROWID | ORDERS | 175K| 3431K| 25979 (3)| 00:05:12 |
| 3 | NESTED LOOPS | | 25300 | 864K| 46764 (3)| 00:09:22 |
|* 4 | TABLE ACCESS BY INDEX ROWID| SHIPMENT_TYPE_METHODS | 1 | 15 | 2 (0)| 00:00
|* 5 | INDEX RANGE SCAN | U_SHIPMENT_TYPE_METHODS | 2 | | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | ORDERS_ORDER_DATE | 176K| | 2371 (8)| 00:00:29 |
Predicate Information (identified by operation id):
2 - filter(("O"."PARENT_ORDER_ID" IS NULL OR "O"."ORDER_TYPE"='G' AND
"O"."PARENT_ORDER_ID"=TO_NUMBER("O"."ORIGINAL_ORDER_NUMBER")) AND NVL("O"."PRIORITY",'1')<>'2
AND "O"."SHIPMENT_CLASS_CODE"="STM"."SHIPMENT_CLASS_CODE")
4 - filter("STM"."SURCHARGE_AMOUNT"=0)
5 - access("STM"."CLIENT"=:CLIENT_NUMBER)
6 - access("O"."CLIENT"=:CLIENT_NUMBER)
filter("O"."STATUS"='A' OR "O"."STATUS"='U')
Statistics
55 recursive calls
0 db block gets
7045 consistent gets
0 physical reads
0 redo size
206 bytes sent via SQL*Net to client
238 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> disconnect
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> The TKPROF output for this statement looks like the following:
SELECT count(*)
FROM orders o,shipment_type_methods stm
WHERE o.status in ('A','U')
AND (o.parent_order_id is null
OR (o.order_type = 'G'
AND o.parent_order_id = o.original_order_number))
AND nvl(o.priority,'1') <> '2'
AND o.client = stm.client
AND o.shipment_class_code = stm.shipment_class_code
AND stm.surcharge_amount = 0
AND o.client = :CLIENT_NUMBER
GROUP BY o.client
call count cpu elapsed disk query current rows
Parse 1 0.01 0.00 0 0 0 0
Execute 1 0.04 0.04 0 0 0 0
Fetch 2 2.96 2.91 0 7039 0 1
total 4 3.01 2.95 0 7039 0 1
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 95
Rows Row Source Operation
1 SORT GROUP BY NOSORT (cr=7039 pr=0 pw=0 time=2913701 us)
91 TABLE ACCESS BY INDEX ROWID ORDERS (cr=7039 pr=0 pw=0 time=261997906 us)
93 NESTED LOOPS (cr=6976 pr=0 pw=0 time=20740 us)
1 TABLE ACCESS BY INDEX ROWID SHIPMENT_TYPE_METHODS (cr=2 pr=0 pw=0 time=208 us)
3 INDEX RANGE SCAN U_SHIPMENT_TYPE_METHODS (cr=1 pr=0 pw=0 time=88 us)(object id 81957)
91 INDEX RANGE SCAN ORDERS_ORDER_DATE (cr=6974 pr=0 pw=0 time=70 us)(object id 81547)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 0.02 0.02
********************************************************************************The DBMS_XPLAN.DISPLAY_CURSOR output:
SQL> variable CLIENT_NUMBER varchar2(20)
SQL> exec :CLIENT_NUMBER := '14'
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.06
SQL> SELECT /*+ gather_plan_statistics */ count(*)
2 FROM orders o,shipment_type_methods stm
3 WHERE o.status in ('A','U')
4 AND (o.parent_order_id is null
5 OR (o.order_type = 'G'
6 AND o.parent_order_id = o.original_order_number))
7 AND nvl(o.priority,'1') <> '2'
8 AND o.client = stm.client
9 AND o.shipment_class_code = stm.shipment_class_code
10 AND stm.surcharge_amount = 0
11 AND o.client = :CLIENT_NUMBER
12 GROUP BY o.client
13 /
COUNT(*)
91
Elapsed: 00:00:02.85
SQL> set termout on
SQL> select * from table(dbms_xplan.display_cursor(null, null, 'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
SQL_ID 4nfj368y8w6a3, child number 0
SELECT /*+ gather_plan_statistics */ count(*) FROM orders o,shipment_type_methods stm WHERE
o.status in ('A','U') AND (o.parent_order_id is null OR (o.order_type = 'G'
AND o.parent_order_id = o.original_order_number)) AND nvl(o.priority,'1') <> '2' AND
o.client = stm.client AND o.shipment_class_code = stm.shipment_class_code AND
stm.surcharge_amount = 0 AND o.client = :CLIENT_NUMBER GROUP BY o.client
Plan hash value: 559278019
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
| 1 | SORT GROUP BY NOSORT | | 1 | 1 | 1 |00:00:02.63 | 7039 |
|* 2 | TABLE ACCESS BY INDEX ROWID | ORDERS | 1 | 175K| 91 |00:03:56.87 | 7039 |
| 3 | NESTED LOOPS | | 1 | 25300 | 93 |00:00:00.02 | 6976 |
|* 4 | TABLE ACCESS BY INDEX ROWID| SHIPMENT_TYPE_METHODS | 1 | 1 | 1 |00:00:00.01 | 2 |
|* 5 | INDEX RANGE SCAN | U_SHIPMENT_TYPE_METHODS | 1 | 2 | 3 |00:00:00.01 | 1 |
|* 6 | INDEX RANGE SCAN | ORDERS_ORDER_DATE | 1 | 176K| 91 |00:00:00.01 | 6974 |
Predicate Information (identified by operation id):
2 - filter((("O"."PARENT_ORDER_ID" IS NULL OR ("O"."ORDER_TYPE"='G' AND
"O"."PARENT_ORDER_ID"=TO_NUMBER("O"."ORIGINAL_ORDER_NUMBER"))) AND NVL("O"."PRIORITY",'1')<>'
"O"."SHIPMENT_CLASS_CODE"="STM"."SHIPMENT_CLASS_CODE"))
4 - filter("STM"."SURCHARGE_AMOUNT"=0)
5 - access("STM"."CLIENT"=:CLIENT_NUMBER)
6 - access("O"."CLIENT"=:CLIENT_NUMBER)
filter(("O"."STATUS"='A' OR "O"."STATUS"='U'))
32 rows selected.
Elapsed: 00:00:01.30
SQL> I'm looking forward for suggestions how to improve the performance of this statement.
Thanks
SandyPlease find explain plan for No hint
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 559278019
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 35 | 46764 (3)| 00:09:22 |
| 1 | SORT GROUP BY NOSORT | | 1 | 35 | 46764 (3)| 00:09:22 |
|* 2 | TABLE ACCESS BY INDEX ROWID | ORDERS | 175K| 3431K| 25979 (3)| 00:05:12 |
| 3 | NESTED LOOPS | | 25300 | 864K| 46764 (3)| 00:09:22 |
|* 4 | TABLE ACCESS BY INDEX ROWID| SHIPMENT_TYPE_METHODS | 1 | 15 | 2 (0)| 00:00
|* 5 | INDEX RANGE SCAN | U_SHIPMENT_TYPE_METHODS | 2 | | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | ORDERS_ORDER_DATE | 176K| | 2371 (8)| 00:00:29 |
Predicate Information (identified by operation id):
2 - filter(("O"."PARENT_ORDER_ID" IS NULL OR "O"."ORDER_TYPE"='G' AND
"O"."PARENT_ORDER_ID"=TO_NUMBER("O"."ORIGINAL_ORDER_NUMBER")) AND NVL("O"."PRIORITY",'1')<>'2
AND "O"."SHIPMENT_CLASS_CODE"="STM"."SHIPMENT_CLASS_CODE")
4 - filter("STM"."SURCHARGE_AMOUNT"=0)
5 - access("STM"."CLIENT"=:CLIENT_NUMBER)
6 - access("O"."CLIENT"=:CLIENT_NUMBER)
filter("O"."STATUS"='A' OR "O"."STATUS"='U')
24 rows selected.
Elapsed: 00:00:00.86Explain Plan for Parallel Hint
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 559278019
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 35 | 46764 (3)| 00:09:22 |
| 1 | SORT GROUP BY NOSORT | | 1 | 35 | 46764 (3)| 00:09:22 |
|* 2 | TABLE ACCESS BY INDEX ROWID | ORDERS | 175K| 3431K| 25979 (3)| 00:05:12 |
| 3 | NESTED LOOPS | | 25300 | 864K| 46764 (3)| 00:09:22 |
|* 4 | TABLE ACCESS BY INDEX ROWID| SHIPMENT_TYPE_METHODS | 1 | 15 | 2 (0)| 00:00
|* 5 | INDEX RANGE SCAN | U_SHIPMENT_TYPE_METHODS | 2 | | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | ORDERS_ORDER_DATE | 176K| | 2371 (8)| 00:00:29 |
Predicate Information (identified by operation id):
2 - filter(("O"."PARENT_ORDER_ID" IS NULL OR "O"."ORDER_TYPE"='G' AND
"O"."PARENT_ORDER_ID"=TO_NUMBER("O"."ORIGINAL_ORDER_NUMBER")) AND NVL("O"."PRIORITY",'1')<>'2
AND "O"."SHIPMENT_CLASS_CODE"="STM"."SHIPMENT_CLASS_CODE")
4 - filter("STM"."SURCHARGE_AMOUNT"=0)
5 - access("STM"."CLIENT"='14')
6 - access("O"."CLIENT"='14')
filter("O"."STATUS"='A' OR "O"."STATUS"='U')
24 rows selected.
Elapsed: 00:00:08.92Explain Plan for USE_Hash hint
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 1465232248
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 35 | 46786 (3)| 00:09:22 |
| 1 | SORT GROUP BY NOSORT | | 1 | 35 | 46786 (3)| 00:09:22 |
|* 2 | HASH JOIN | | 25300 | 864K| 46786 (3)| 00:09:22 |
|* 3 | TABLE ACCESS BY INDEX ROWID| SHIPMENT_TYPE_METHODS | 1 | 15 | 2 (0)| 00:00:0
|* 4 | INDEX RANGE SCAN | U_SHIPMENT_TYPE_METHODS | 2 | | 1 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID| ORDERS | 175K| 3431K| 46763 (3)| 00:09:22 |
|* 6 | INDEX RANGE SCAN | ORDERS_ORDER_DATE | 176K| | 4268 (8)| 00:00:52 |
Predicate Information (identified by operation id):
2 - access("O"."CLIENT"="STM"."CLIENT" AND "O"."SHIPMENT_CLASS_CODE"="STM"."SHIPMENT_CLASS_COD
E")
3 - filter("STM"."SURCHARGE_AMOUNT"=0)
4 - access("STM"."CLIENT"='14')
5 - filter(("O"."PARENT_ORDER_ID" IS NULL OR "O"."ORDER_TYPE"='G' AND
"O"."PARENT_ORDER_ID"=TO_NUMBER("O"."ORIGINAL_ORDER_NUMBER")) AND NVL("O"."PRIORITY",'1')<>'2
6 - access("O"."CLIENT"='14')
filter("O"."STATUS"='A' OR "O"."STATUS"='U')
25 rows selected.
Elapsed: 00:00:01.09
SQL> Thanks
Sandy -
Dynamic query in where clause while looping in an internal table.
Hi,
Had a small question : How can i make a dynamic query for the WHERE clause while looping at an internal table.
i want to implement a dynamic where clause query for the below example.
it_cfx_col is an internal table and wa_cfx_col is a work area for it_cfx_col
DATA :
i_cfx_col TYPE TABLE OF cfx_col,
wa_cfx_col LIKE LINE OF i_cfx_col.
DATA : count TYPE i VALUE 0.
DATA : l_where_clause TYPE string,
l_where_clause2 TYPE string,
l_name type string.
l_name = 'NANDANOM'.
l_scenario = 'collaboration'.
LOOP AT it_cfx_col INTO wa_cfx_col
WHERE CREATED_BY = l_name
AND SCENARIO = l_scenario.
count = count + 1.
some business logic implemented using the work area wa_cfx_col
endloop.
Now i want to write a dynamic query for the where clause.
DATA : count TYPE i VALUE 0.
DATA : l_where_clause TYPE string,
l_where_clause2 TYPE string,
l_name type string.
l_name = 'NANDANOM'.
l_scenario = 'collaboration'.
l_where_clause = 'CREATED_BY = l_name'.
l_where_clause2 = 'AND SCENARIO = l_scenario'.
if l_scenario is not initial.
CONCATENATE l_where_clause l_where_clause2
INTO l_where_clause SEPARATED BY space.
endif.
LOOP AT i_cfx_col INTO wa_cfx_col
WHERE (l_where_clause).
count = count + 1.
some business logic implemented using the work area wa_cfx_col
endloop.
when i compile this i get an error message as { Statement concluding with "...(l_where_clause)" ended unexpectedly}
Even i changed the initilization of the variable l_where_clause2 to [ l_where_clause2 = 'AND SCENARIO = l_scenario.'. ]
added the end of line demarkation ".", but still i got the same error message.
Is it a limtation in ABAP that i cannot write a dynamic query for the where clause while looping at an internal table?
Regards,
omHi savita,
there in no such 1 limitaion in abap for dynamic query .. i think the error meassge is only beacuse of your synatx delcartaion.
>> LOOP AT i_cfx_col INTO wa_cfx_col
WHERE (l_where_clause).
count = count + 1.
some business logic implemented using the work area wa_cfx_col
endloop.
afted delclarataion also , in the where statement you should specify both the field name and value bname
LOOP AT i_cfx_col INTO wa_cfx_col
WHERE l_where_clause = 'CREATED_BY = l_name' .
count = count + 1.
hope it helps.
regads
priya.
Maybe you are looking for
-
Subtraction of two key figures normalized to result not working as expected
Hello SAP Community! I am having problems with getting the right result from a subtraction of two KFs which are "normalized to results" which means the KFs really have values expressed as percentages. The substraction that should be performed is of t
-
Is there a video generator for lines?
I'm still drawing circles, squares, and lines to overlay on my videos. Some time ago when I needed to make circles and squares, but didn't know how, someone here (Piero I think) told me about a great plug-in generator called Frames for just that purp
-
Aperture 3.0.2.
Upgrade is out. 3/25/2010
-
Selecting Distribution Rule in any Transaction
When generating journal entry I want to input distribution rule in the row. Now while clicking 'Choose from list' button in 'Distribution Rule' field system pops up an window to select the appropriate rule. But in choose from list window in 'distribu
-
P roblem with Ctrl C on linux systems... makes the OCR CORRUPTED
Hi, I am facing several issues when i am using the Ctrl 'c' option on linux platforms. We are using Oracle 11g R1 clusterware. When the srvctl command hangs, we generally use Ctrl 'c' option to exit from the session. But the registration of database