Avoid Distributed query in PL/SQL cursor code
Hi,
I have to avoid a distributed qry in my cursor code in PL/SQL.
The query follows like this,
cursor c1
is
select a.test,b.test1,a.test2
from apple a,
[email protected] b,
bat c
where a.listid = b.listid
and a.list_name = c.list_name;
Now i need to split the above cursor into two .
(1)I need to query appl and bat which is from local database into one and
(2)Have to do something for the value from [email protected] is stored in a temp. table or PL/SQL table.So that ,i can use the PL/SQL table or temp table in my join in cursor ,instead of having a distributed query.
By doing so,will the performance hit badly ?
[Note: Imagine this scenario is taking place in Oracle 11i Apps]
Regards,
Prasanna Natarajan,
Oracle ERP Tech Team.
[url http://groups.google.de/group/comp.databases.oracle.server/browse_frm/thread/df893cf9be9b2451/54f9cf0e937d7158?hl=de&tvc=1&q=%22Beautified%22+code+runs+slower#54f9cf0e937d7158]Recently somebody complained about slow performance after code was beatified in PL SQL Developer, after recompilation without flag "Add Debug Information" it run faster...
(just a guess)
Best regards
Maxim
Similar Messages
-
Output query results in sql transaction code
Is the code below valid? I think the comma at the end of my
variable is
throwing an error when I run this.
Eg. "#trim(product)#",
I need the comma however to make the statement correct except
after the last
record. Is there any way around that?
<cfquery name="calc" datasource="#client.dsn#"
username="#client.username#"
password="#client.password#">
SELECT *
FROM order_history
WHERE OrderNo='823719'
AND product in (<cfoutput
query="backorders">"#trim(product)#",</cfoutput>)
AND invoice < #max.invoice#
ORDER BY invoice desc
</cfquery>since it looks like you are dealing with strings, take a look
at the
QuotedValueList function.
hth
Tim Carley
www.recfusion.com
[email protected] -
Returning SQL cursor from Stored Procedure
Hi,
I have a query regarding returning sql cursor from stored procedure to java in oracle 11g.
I want to query some data ex: my query returns A, B, C. Also, now I want to query some other data ex: D, E, F. Now I want to return this data as an sql cursor as a single row . Example: A,B,C,D,E,F. Is it possible to return/create a cursor in stored procedure?
assume both query returns equal number of rows.. however both are not related to each other..RP wrote:
Hi,
I have a query regarding returning sql cursor from stored procedure to java in oracle 11g.
I want to query some data ex: my query returns A, B, C. Also, now I want to query some other data ex: D, E, F. Now I want to return this data as an sql cursor as a single row . Example: A,B,C,D,E,F. Is it possible to return/create a cursor in stored procedure?
assume both query returns equal number of rows.. however both are not related to each other..It sounds like what you need is a ref cursor.
First thing to remember though is that cursors do not hold any data (see: {thread:id=886365})
In it's simplest form you would be creating a procedure along these lines...
SQL> create or replace procedure get_data(p_sql in varchar2, p_rc out sys_refcursor) is
2 begin
3 open p_rc for p_sql;
4 end;
5 /
Procedure created.
SQL> var rc refcursor;
SQL> exec get_data('select empno, ename, deptno from emp', :rc);
PL/SQL procedure successfully completed.
SQL> print rc;
EMPNO ENAME DEPTNO
7369 SMITH 20
7499 ALLEN 30
7521 WARD 30
7566 JONES 20
7654 MARTIN 30
7698 BLAKE 30
7782 CLARK 10
7788 SCOTT 20
7839 KING 10
7844 TURNER 30
7876 ADAMS 20
7900 JAMES 30
7902 FORD 20
7934 MILLER 10
14 rows selected.
SQL> exec get_data('select deptno, dname from dept', :rc);
PL/SQL procedure successfully completed.
SQL> print rc
DEPTNO DNAME
10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONS
50 IT SUPPORTWhich takes an SQL statement (as you said that both your queries were unrelated), and returns a ref cursor, and then your Java code would fetch the data using that cursor.
Now, as for getting your rows to columns and combining two queries that do that... something along these lines...
SQL> select * from x;
C
A
B
C
SQL> select * from y;
C
D
E
F
SQL> ed
Wrote file afiedt.buf
1 select x.col1, x.col2, x.col3
2 ,y.col1 as col4
3 ,y.col2 as col5
4 ,y.col3 as col6
5 from (
6 select max(decode(rn,1,col1)) as col1
7 ,max(decode(rn,2,col1)) as col2
8 ,max(decode(rn,3,col1)) as col3
9 from (select col1, rownum rn from (select * from x order by col1))
10 ) x
11 cross join
12 (
13 select max(decode(rn,1,col1)) as col1
14 ,max(decode(rn,2,col1)) as col2
15 ,max(decode(rn,3,col1)) as col3
16 from (select col1, rownum rn from (select * from y order by col1))
17* ) y
SQL> /
C C C C C C
A B C D E F... will do what you ask. For further information about turning rows to columns read the FAQ: {message:id=9360005} -
Query in PL/SQL code is slower
I have a very strange issue within my development database, I'm using Oracle 10g.
I created a query to read some data from a large collection of tables -OFDM tables- I have tested and tuned the performance of the query from (PL/SQL Developer 7 ), it takes only 2 minutes to finish but when I use the same query as a cursor in a database procedure it consume a lot of time around 15 min to get the data.
Your help is appreciated[url http://groups.google.de/group/comp.databases.oracle.server/browse_frm/thread/df893cf9be9b2451/54f9cf0e937d7158?hl=de&tvc=1&q=%22Beautified%22+code+runs+slower#54f9cf0e937d7158]Recently somebody complained about slow performance after code was beatified in PL SQL Developer, after recompilation without flag "Add Debug Information" it run faster...
(just a guess)
Best regards
Maxim -
How to Execute sql query in PL/SQL ( a variable) with out using Cursor or REF cursor
Hi
I am building a dynamic query based on some conditions
as an example
v_query varchar2(2000);
x1 varchar2(20);
y1 varchar2(20);
z1 varchar2(20);
v_query := ' Select x,y,z into x1,y1,z1 From ... ';
Is there any way to execute the query with out using cursor or ref cursor..
Thanks
ArunBoth Tod and Eric provided valid responses given the format of the queory you supplied. Howver, if you want to use dynamic sql in either way, you need to be absolutely certain that your query will always only return a single row (e.g. SELECT COUNT(*) FROM mytable), because if it retuns more than one, your procedure will break unless you have an exception handler to handle either TOO_MANY_ROWS or OTHERS.
If you want to pull in a lot of data without walking a cursor, you should look at the BULK COLLECT options. -
PL/SQL cursor-collection related query
Hi all,
I have a function which will take a collection (table of numbers) as a input argument.
Each id in the collection corresponds to a set of columns.I need to return a cursor which will contain the resultsets for all the ids in the collection.How do i do it.
what should the query be ?
say each id has three columns a,b,c to be returned.
I am given the collection of ids and am supposed to return a cursor which will have a,b,c columns for all the ids.
For individual ids , its straight forward
select a,b,c from sometable where id=input_id.
But how do i construct the cursor given a collection of ids?
Thanks in advance.Hi,
Please see the below example:
SQL>CREATE TABLE T ( ID NUMBER(2),a NUMBER(2),b NUMBER(2),c NUMBER(2));
Table created.
SQL>SELECT * FROM t;
ID A B C
1 12 13 15
2 21 31 51
2 rows selected.
SQL>
Use the below query to create your cursor :
SQL>SELECT a,b,c FROM t tb1, TABLE( TBL_TYPE(1,2)) tb2 WHERE tb1.id = tb2.column_value;
A B C
12 13 15
21 31 51
2 rows selected.
SQL>Regards -
CR+LF Code at the end of each record selected in sql cursor
i am selecting some data records in a sql cursor and writing it into a file using UTL_FILE.puT in a plsql procedure.
at the end of select statement if i add ||chr(13||chr(10) iam getting CR+CR+LF code
if i add only || chr(10) i am getting LF code.
What i need is only CR+LF code. Kindly help to use any other commands.
Thanks,
Shivaji.
Edited by: Shivaji M on Apr 22, 2010 12:11 AM
Edited by: Shivaji M on Apr 22, 2010 12:36 AMIt's in the book!
"PUT_LINE terminates the line with the platform-specific line terminator character or characters."
http://download.oracle.com/docs/cd/E11882_01/appdev.112/e10577/u_file.htm#i997640 -
Please reply:how to avoid extra trailing spaces while using cursor sharing
i am using cursor sharing with FORCE or SIMILAR.
what is the solution to avoid extra trailing spaces without any java code change.
do we have any option in oracle to avoid extra trailing spaces during the query processing ?
I am using Oracle 10g
CURSOR SHARING is a feature in which multiple sql statements
which are same will have a shared cursor (in the library cache) for an oracle session,
i.e, the first three steps of the sql processing (hard parse, soft parse, optimization)
will be done only the first time that kind of statement is executed.
There are two ways in which similar SQL statements with different condition values can be made to "SHARE" cursor during execution:
1. Writing SQLs with Bind Variables: SQLs having no hard coded literals in them
For e.g., the query below
SELECT node.emp_name AS configid
FROM emp node
WHERE emp_no = :1
AND dept_no =
DECODE (SUBSTR (:2, 1, 3),
:3, :4,
(SELECT MAX (dept_no)
FROM emp
WHERE emp_no = :5 AND dept_no <= :6)
AND node.dept_type = :7
ORDER BY node.emp_name
Here all the variables are dynamically bound during the execution. The ":X" represents BIND Variable and the actual values are bound to the SQL only at the 4th step of the execution of the SQL.
In applications: The queries written with "?" as bind variables will be converted into ":X" and are sqls with Bind Variables.
2. The CURSOR_SHARING parameter: Only Useful for SQL statements containing literals:
For eg., the query below:
SELECT node.emp_name AS configid
FROM emp node
WHERE emp_no = 'H200'
AND dept_no =
DECODE (SUBSTR (:1, 1, 3),
'PLN', :2,
(SELECT MAX (dept_no)
FROM emp
WHERE emp_no = :3 AND dept_no <= :4)
AND node.dept_type = :5
ORDER BY node.emp_name
In the query above, there are two hard coded literals H200 , PLN. In this case when the same SQL executed with different values like (H2003 , PLN), oracle will create a new cursor for this statement and all the first three steps ( hard & soft parse and optimization plan) needs to be done again.
This can be avoided by changing the CURSOR_SHARING parameter which can be set to any of three values:
1. EXACT: Causes the mechanism not be used, i.e. no cursor sharing for statements with different literals. This is the default value.
2. FORCE: Causes unconditional sharing of SQL statements that only differ in literals.
3. SIMILAR: Causes cursor sharing to take place when this is known not to have any impact on optimization.
So, FORCE and SIMILAR values of the parameter will be helping in cursor sharing and improve the performance of the SQLs having literals.
But here the problem arises if we use the FORCE and SIMILAR other than EXACT.
alter session set cursor_sharing ='EXACT'
select 1 from dual;
'1'
1
alter session set curson_sharing='FORCE'
select 2 from dual;
'2'
2
alter session set curson_sharing='SIMILAR'
select 3 from dual;
'3'
3
So, this will give extra trailing spaces in when we retrieve from java method and any
further java processing based on the hardcoded literal values will fail. this needs lot of
effort in remodifying the existing millions of lines of code.
My question is i have to use cursor sharing with FORCE or SIMILAR and can't we do the trimming
from the oracle query processing level ?
please help me on this ?
Message was edited by:
Leeladhar
Message was edited by:
LeeladharPlease reply to this thread
How to avoid extr trailing spaces using Cursor sharing opton FORCE, SIMILAR -
How to avoid performance problems in PL/SQL?
How to avoid performance problems in PL/SQL?
As per my knowledge, below some points to avoid performance proble in PL/SQL.
Is there other point to avoid performance problems?
1. Use FORALL instead of FOR, and use BULK COLLECT to avoid looping many times.
2. EXECUTE IMMEDIATE is faster than DBMS_SQL
3. Use NOCOPY for OUT and IN OUT if the original value need not be retained. Overhead of keeping a copy of OUT is avoided.Susil Kumar Nagarajan wrote:
1. Group no of functions or procedures into a PACKAGEPutting related functions and procedures into packages is useful from a code organization standpoint. It has nothing whatsoever to do with performance.
2. Good to use collections in place of cursors that do DML operations on large set of recordsBut using SQL is more efficient than using PL/SQL with bulk collects.
4. Optimize SQL statements if they need to
-> Avoid using IN, NOT IN conditions or those cause full table scans in queriesThat is not true.
-> See to queries they use Indexes properly , sometimes Leading index column is missed out that cause performance overheadAssuming "properly" implies that it is entirely possible that a table scan is more efficient than using an index.
5. use Oracle HINTS if query can't be further tuned and hints can considerably help youHints should be used only as a last resort. It is almost certainly the case that if you can use a hint that forces a particular plan to improve performance that there is some problem in the underlying statistics that should be fixed in order to resolve issues with many queries rather than just the one you're looking at.
Justin -
Assigning a query dynamically to a cursor based on IF ELSE condotion
hello guys,
we are facing a problem while creating a procedure.
The procedure has been recreated in ORACLE from SQL SERVER 2005.
the problem is that in SQL server we can assign a query dynamically to a cursor so that it will be called at execution time.But this is not the case in oracle, i.e in Oracle its not allowed to assign a query to a cursor dynamically(OR IS IT...!!!)
the code is
vr_SQL varchar2(400);
declare
cursor ord_cur ; <-----cursor declaration
begin
If v_pIsScrutiny = 0 then +<--------------second condition+
vr_SQL:='Select NVL(ServiceID,0) ServiceID,OrdQty,+<-------query assignment to a variable+
NVL(DrugID,0) DrugID,NVL(ServiceAmount,0) Rate,OrdDtlID
from Orderdtl inner join ordermst on Orderdtl.OrdID = ordermst.OrdID
Where Orderdtl.OrdID in (Select OrdID From Ordermst Where OrdVisitID = vr_visitid
and TO_CHAR(ordermst.OrdDate,''DD-MON-YYYY'')
Between TO_CHAR(vr_pActivationDate,''DD-MON-YYYY'')
and TO_CHAR(vr_pExpiryDate,''DD-MON-YYYY'')
) And NVL(Orderdtl.Cancelled,0) = 0 And NVL(Orderdtl.PackageID,0) = 0
and NVL(Orderdtl.DrugID,0) = 0;';
Else +<--------------first condition+
Update OrderDtl Set PackageID = 0 , AllocationID = 0 , ConsumptionID = 0
Where OrdID in (Select OrdID From Ordermst Where OrdVisitID = vr_visitid)
And AllocationID = v_pHCPAllocationID;
vr_SQL:= 'Select NVL(ServiceID,0) ServiceID, +<-------query assignment to a variable+
OrdQty,NVL(DrugID,0) DrugID,NVL(ServiceAmount,0)
Rate,OrdDtlID
from Orderdtl inner join ordermst on Orderdtl.OrdID = ordermst.OrdID
Where Orderdtl.OrdID in (Select OrdID From Ordermst Where OrdVisitID = vr_visitid
and TO_CHAR(ordermst.OrdDate,''DD-MON-YYYY'')
Between TO_CHAR(vr_pActivationDate,''DD-MON-YYYY'')
and TO_CHAR(vr_pExpiryDate,''DD-MON-YYYY'')
) And NVL(Orderdtl.Cancelled,0) = 0 And NVL(Orderdtl.PackageID,0) = 0;';
end if;
ord_cur is vr_SQL; +<----------query assigned to a cursor variable+
ord_rec ord_cur%ROWTYPE;
if not ord_cur%ISOPEN then
open ord_cur;
end if;
loop
fetch ord_cur into ord_rec;
exit when ord_cur%NOTFOUND;So currently we are stuck with this problem.
Any solution would be of great help..
thank you841363 wrote:
hello guys,
we are facing a problem while creating a procedure.
The procedure has been recreated in ORACLE from SQL SERVER 2005.
the problem is that in SQL server we can assign a query dynamically to a cursor so that it will be called at execution time.But this is not the case in oracle, i.e in Oracle its not allowed to assign a query to a cursor dynamically(OR IS IT...!!!)The problem is that you are thinking in SQL Server terms and Oracle just isn't SQL Server.
You need to consider using ref cursors for such things (sys_refcursor) e.g.
SQL> CREATE OR REPLACE PACKAGE reftest IS
2 PROCEDURE test(P_no in number, cur_o OUT sys_refcursor);
3 end;
4 /
Package created.
SQL>
SQL> CREATE OR REPLACE PACKAGE body reftest as
2 PROCEDURE test(P_no in number, cur_o OUT sys_refcursor) as
3 myexc exception;
4 BEGIN
5 if P_no = 1 then
6 open cur_o for select empno, ename from emp;
7 elsif p_no =2 then
8 open cur_o for select deptno, dname from dept;
9 else
10 RAISE myexc;
11 END IF;
12 exception
13 when myexc then
14 raise_application_error(20991,'input must be 1 or 2');
15 end ;
16 end reftest;
17 /
Package body created.
SQL> var x refcursor;
SQL> exec reftest.test(1,:x);
PL/SQL procedure successfully completed.
SQL> print x;
EMPNO ENAME
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
14 rows selected.
SQL> exec reftest.test(2,:x);
PL/SQL procedure successfully completed.
SQL> print x;
DEPTNO DNAME
10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONS
SQL> -
Need help on Dynamic SQL Cursor in Forms
Hi All,
I am trying to execute Dynamic SQL Cursor in forms using EXEC_SQL built in.
I have a cursor for example:
'select * from supplier where supplier = '||p_supplier||' and processing_order = '||p_order
My code is
cur_num := Exec_SQL.Open_cursor;
sql_order := 'select * from supplier where supplier = '||p_supplier||' and processing_order = '||p_order;
EXEC_SQL.PARSE(cursor_number, sql_order);
EXEC_SQL.DEFINE_COLUMN(cur_num ,1,ln_Supp_Id);
EXEC_SQL.DEFINE_COLUMN(cur_num ,2,ls_Suppl_Name,30);
EXEC_SQL.DEFINE_COLUMN(cur_num ,24,ls_exchange,20);
sql_count := EXEC_SQL.EXECUTE(cur_num );
While EXEC_SQL.FETCH_ROWS(cur_num ) > 0 Loop
EXEC_SQL.COLUMN_VALUE(cur_num ,1,ln_Supp_Id);
EXEC_SQL.COLUMN_VALUE(cur_num ,2,ls_Suppl_Name);
EXEC_SQL.COLUMN_VALUE(cur_num ,24,ls_exchange);
End Loop;
EXEC_SQL.CLOSE_CURSOR(cur_num );
In this case I have to write 24 Define Columns and 24 Column value. Is there any way to assign them to %rowtype at one time as I need all coulmn of the table.
I had similar case on multiple tables.
Please help me
Thanks,
MaddyI need this dynamic sql because p_supplier and p_order values changes at run time
I do not understand. Is this a simplified sample or the real thing? You do know that you can pass variables to cursors:
cursor test is
select * from supplier where supplier = p_supplier and processing_order = p_order;
or does e.g. p_supplier hold other parts of the query?
cheers -
Need a column based off a PL/SQL cursor, how to do this?
Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
With the Real Application Testing option
JServer Release 9.2.0.8.0 - Production
Report Builder 10.1.2.2.0
ORACLE Server Release 10.1.0.5.0
Oracle Procedure Builder 10.1.2.2.0
Oracle ORACLE PL/SQL V10.1.0.5.0 - Production
Oracle CORE 10.1.0.5.0 Production
Hi,
I am trying to create a fairly basic report but in the initial data model query, I have one column that is built based off of a PL/SQL cursor. How do I add this into my report? I have tried to create a function under Program Units and reference the function in my select statement for the data model however it keeps saying it is an invalid identifier, and I assume its looking in our database and not the function I created inside the report.
This is what it looks like:
SELECT a.id,
b.name,
F_GET_GENERIC_NAME(b.code) "Generic Name",
c.strength...and the function i want it to use in my report:
FUNCTION F_GET_GENERIC_NAME (in_code varchar2) RETURN VARCHAR2 IS
BEGIN
DECLARE
generic_name table.column%TYPE;
CURSOR cs_get_generic_name IS
SELECT /*+ USE_HASH (AR) */ desc
FROM a_ref AR, ai_ic AC
WHERE AC.code = in_code
AND AC.code = AR.code
ORDER BY sort_nbr;
BEGIN
generic_name := '';
FOR v_get_generic_name IN cs_get_generic_name
LOOP
generic_name := generic_name || RTRIM(v_get_generic_name.desc)
|| '/' || ' ';
END LOOP;
generic_name := SUBSTR(generic_name, 1,(NVL(LENGTH(generic_name), 0) - 2));
RETURN generic_name;
END;
END;
Any suggestions? Should I just create the function in the database?I am trying to do it through a formula column but am encountering the following problem.
I've created a formula column in my data model where I want the column to be (inside the group).
Inside the PL/SQL for the column I reference the function that I had previously created with the following:
function CF_Generic_nameFormula return Char is
begin
F_GET_GENERIC_NAME(:code);
end;However it won't let me compile, giving the error that "F_GET_GENERIC_NAME is not a procedure or is undefined." Is there something else that I am missing?
EDIT: Nevermind, i missed something simple like putting a return in front of the function call.
Edited by: a small rabbit on Nov 3, 2009 10:43 AM
Edited by: a small rabbit on Nov 3, 2009 10:44 AM -
I have gotten this to work in my Reports class but can not get this to work at my company. Basically I'm trying to use the JDBC query in Report Builder.
Here is my Ref Cursor Code:
CREATE OR REPLACE PACKAGE SCOTT.types is
type sqlcur is REF cursor;
end;
Here is my Pl/SQL function:
CREATE OR REPLACE FUNCTION SCOTT.test return Scott.types.sqlcur is
c1 Scott.types.sqlcur;
begin
open c1 for select * from scott.emp;
return c1;
end;
I can get this to work in SQL Plus by doing the following:
var r refcursor
exec :r := test;
print r When I go into Reports Builder->JDBC query I connect to the SCOTT db using tiger as the password. I type in the function name TEST and get the error "wrong number or types of arguments in call TEST". I have tried "call TEST" but that doesnt work either. If I use "call TEST" I get an error saying it expected characters ":=(@" etc....
I know my connection works because I can do a "select * from emp" and get results. Can anyone get this to work?
I'm running Report Builder 9.0.2.0.3
I have done multiple searches on this issue and most responses point someone to links that dont work or documentation. I have read them and my code above should work but doesnt........Please put some real examples or code that works with the "Scott" schema.
Thankshi Shawn
When running jdbc quesry based on SP with Oracle DB, the first parameter of the store procedure should be of ref cursor type and it shall be a OUT parameter.
For example:
CREATE OR REPLACE PACKAGE jdbcpdspkg AS
TYPE Empcur IS ref cursor ;
procedure proc_with_param (p_emp_cv out jdbcpdspkg .empcur, p1 in number, p2 in number , p3 in number, p4 in number , p5 in number) ;
Thanks
Rohit -
I need somebody to help me with sql cursors, in JSP.
This is my peace of code what is wrong with it?
Statement stmt = myConn.createStatement();
stmt.executeQuery("BEGIN WORK");
stmt.executeQuery("DECLARE item_cursor CURSOR FOR SELECT user_name FROM admin_info");
stmt.executeQuery("FETCH 10 FROM item_cursor");
ResultSet rs = stmt.getResultSet();
while(rs.next()){
if(rs.getString(1) != null){
user_name = rs.getString(1).trim();
%><P><%= user_name %></P><%
stmt.executeQuery("CLOSE item_cursor");
stmt.executeQuery("COMMIT WORK");
and this is the error that a get: No results where returned by the query
Please help anybody
thanx guysIf you are using ORACLE drivers and classes.
This sample program shows Oracle JDBC REF CURSOR functionality, creating a PL/SQL package that includes a stored function that returns a REF CURSOR type. The sample retrieves the REF CURSOR into a result set object.
* This sample shows how to call a PL/SQL function that opens
* a cursor and get the cursor back as a Java ResultSet.
import java.sql.*;
import java.io.*;
import oracle.jdbc.driver.*;
class RefCursorExample
public static void main (String args [])
throws SQLException
// Load the driver
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
// Connect to the database
// You can put a database name after the @ sign in the connection URL.
Connection conn =
DriverManager.getConnection ("jdbc:oracle:oci8:@", "scott", "tiger");
// Create the stored procedure
init (conn);
// Prepare a PL/SQL call
CallableStatement call =
conn.prepareCall ("{ ? = call java_refcursor.job_listing (?)}");
// Find out all the SALES person
call.registerOutParameter (1, OracleTypes.CURSOR);
call.setString (2, "SALESMAN");
call.execute ();
ResultSet rset = (ResultSet)call.getObject (1);
// Dump the cursor
while (rset.next ())
System.out.println (rset.getString ("ENAME"));
// Close all the resources
rset.close();
call.close();
conn.close();
// Utility function to create the stored procedure
static void init (Connection conn)
throws SQLException
Statement stmt = conn.createStatement ();
stmt.execute ("create or replace package java_refcursor as " +
" type myrctype is ref cursor return EMP%ROWTYPE; " +
" function job_listing (j varchar2) return myrctype; " +
"end java_refcursor;");
stmt.execute ("create or replace package body java_refcursor as " +
" function job_listing (j varchar2) return myrctype is " +
" rc myrctype; " +
" begin " +
" open rc for select * from emp where job = j; " +
" return rc; " +
" end; " +
"end java_refcursor;");
stmt.close(); -
Hi All,
I have a distributed deployment of two oracle instances where database A keeps a replication of a schema from database B.
I have A and B linked together, B sees A as a remote database, and my application sends queries to database B.
Let's say I have the following two queries:
The following is issued to B:
select * from magic.accountejb@A a where a.profile_userid = ( select userid from magic.accountprofileejb@A ap where ap.userid = 'uid:174')
and the following issued directly to A (which is basically the same query as above):
select * from accountejb a where a.profile_userid = ( select userid from accountprofileejb ap where ap.userid = 'uid:174')
when I measure the time through my Java application, the second query executes more than 3 times faster than the first query (23ms on A compared to 80ms on B). However, when I use the sqlplus client on B to issue the exact same query, the execution time reported by sqlplus is almost identical to the second one(20ms).
When I monitor the execution plan through *@UTLXPLAN*, it seems like the query sent to B is also fully executed remotely and on A. with a network latency of 11ms between A and B, I am not sure why I see such a long delay for the first query. Also playing with DRIVING_SITE did not have any perceived effect on improving performance.
I wonder if anybody has any explanation for the difference I see? is a distributed query really 3 times slower than a regular query even though both are pretty much handled by the same database engine? or is it so that I need some other sort of tuning?
Any thoughts or advice on how I can achieve comparable performance is highly appreciated.
thanks!
Edited by: 944957 on 16-Nov-2012 20:25
Edited by: 944957 on 16-Nov-2012 20:29Thanks a lot for the quick response:
rp0428 wrote:
1. the 4 digit Oracle version (or other DB version)
2. the JDK version
3. the JDBC jar name and versionI am using ojdbc14 with Oracle 11g XE and JDK 7.
4. the code you are using that shows an issue or problem.The queries I am using is basically the two queries I provided earlier, and here is the exact Java code. I loop over the code below 20 times and discard the first two retrieved results for each query and calculate an average on the remaining 18 results collected.
static Connection c1 = null, c2 = null;
static Statement _session;
public void getStats(){
long start;
for (int i = 0; i < 20; i++) {
c1 = (c1 != null) ? c1 :
DriverManager.getConnection("jdbc:oracle:thin:@//" + System.getProperty("host.1")+"/XE", "magic", "magic");
_session = c1.createStatement();
session.executeUpdate("ALTER SESSION SET CURRENTSCHEMA=magic");
start = System.currentTimeMillis();
_session.executeUpdate(query);
values[0] = System.currentTimeMillis() - start;
_session.close();
c2 = (c2 != null) ? c2 :
DriverManager.getConnection("jdbc:oracle:thin:@//" + System.getProperty("host.2")+"/XE", "magic", "magic");
_session = c2.createStatement();
_session.executeUpdate("ALTER SESSION SET CURRENT_SCHEMA=magic");
start = System.currentTimeMillis();
_session.executeUpdate(distQuery);
values[1] = System.currentTimeMillis() - start;
_session.close();
} // end for loop
} // end method
5. for performance related issues - the data volume being queried or processedThe data volume is rather small. I measure the data and it is roughly about 10K of data transfer.
>
Without seeing the code to see how you are measuring the timing it is hard to comment on what you posted.
3. How was the timing computed in sql*plus?for sqlplus, I issue *set timing on* prior to executing the queries.
4. Were the connections already created before the timing started? Or is the creation of the connection part of the timing result?As you see in the code, the connection is only created the first time I issue a query, and I discard the results of the first two queries using the connection as the timing is far off specially for the first query. I think the first query also download some metadata information that I don't consider in calculating the performance.
5. Do the timings include the retrieval of ALL result set data? Or just the first set of results?the time only consists of executing the first set.
Can you post the explain plans for the java and the sql*plus executions?Here is the results of the explain plan
PLAN_TABLE_OUTPUT
Plan hash value: 3819315806
| Id | Operation | Name | Rows | Bytes | Cos
t (%CPU)| Time | Inst |
PLAN_TABLE_OUTPUT
| 0 | SELECT STATEMENT REMOTE | | 1 | 43 |
2 (0)| 00:00:01 | |
| 1 | TABLE ACCESS BY INDEX ROWID| ACCOUNTEJB | 1 | 43 |
2 (0)| 00:00:01 | CORONA |
|* 2 | INDEX RANGE SCAN | ACCOUNT_USERID | 1 | |
1 (0)| 00:00:01 | CORONA |
|* 3 | INDEX UNIQUE SCAN | PK_ACCOUNTPROFILEEJB | 1 | 9 |
0 (0)| 00:00:01 | CORONA |
PLAN_TABLE_OUTPUT
Predicate Information (identified by operation id):
2 - access("A1"."PROFILE_USERID"= (SELECT "A2"."USERID" FROM "MAGIC"."A
CCOUNTPROFILEEJB"
PLAN_TABLE_OUTPUT
"A2" WHERE "A2"."USERID"='uid:174'))
3 - access("A2"."USERID"='uid:174')
Note
- fully remote statement
Edited by: 944957 on 16-Nov-2012 20:51
Edited by: 944957 on 16-Nov-2012 20:53
Edited by: 944957 on 16-Nov-2012 20:55
Edited by: 944957 on 16-Nov-2012 20:56
Edited by: 944957 on 16-Nov-2012 20:57
Edited by: 944957 on 16-Nov-2012 20:59
Maybe you are looking for
-
My IPod Touch 4g won't charge or sync, how do I fix it?
I had my IPod Touch 4 generation for 2 years now and suddenly my ipod won't connect to my laptop nor to any other computer source in my household. Before my IPod would only sync and not charge, so I would had to figit with the sync cable connected to
-
hi all, My problem is the dvd drive in my laptop. It will not read dvd's commercial or burnt variety, curiously it reads cd's just fine. So far email tech support has been useless. I wrote them explaining what steps I had tried to fix the problem suc
-
Hi All How can I assign a protect resource in a protected authorization policy to a specific user ? in the protected authentication policy , the user need to authenticate against LDAP and then he can get in but still denied the access but how can I g
-
Query on ABAP List Viewer and Table Control?
Hi all, I was trying to solve the exercises in these areas....but was unable to do as some of the concepts were not clear to me as I'm new to this field. So Can any one help me out in giving me the Notes or attachments on the ABAP List Viewer(A.L.V.)
-
Relocated distributed SQL Server database
Hi All, I have a distributed installation; SQL Server on one host, Application Server on another separate host. I need to move just the database to a different physical host. I'm not changing the <SID> and I want to simply start up the Application se