Using a query with bind variable with columns defined as raw

Hi,
We are on Oracle 10.2.0.4 on Solaris 8. I have a table that has 2 columns defined as raw(18). I have a query from the front end that queries these two raw columns and it uses bind vairables. The query has a performance issue that I need to reproduce but my difficulty is that how to test the query in sqlplus using bind variables (the syntax for bind vairables fails for columns with raw datatype).
SQL> DESC TEST
Name                                      Null?    Type
ID1                                                RAW(18)
ID2                                                RAW(18)
SQL> variable b1  RAW(18);
Usage: VAR[IABLE] [ <variable> [ NUMBER | CHAR | CHAR (n [CHAR|BYTE]) |
                    VARCHAR2 (n [CHAR|BYTE]) | NCHAR | NCHAR (n) |
                    NVARCHAR2 (n) | CLOB | NCLOB | REFCURSOR |
                    BINARY_FLOAT | BINARY_DOUBLE ] ]
The above is the error I get - i cant declare a variable as raw.
SQL> variable b2  RAW(18);
Usage: VAR[IABLE] [ <variable> [ NUMBER | CHAR | CHAR (n [CHAR|BYTE]) |
                    VARCHAR2 (n [CHAR|BYTE]) | NCHAR | NCHAR (n) |
                    NVARCHAR2 (n) | CLOB | NCLOB | REFCURSOR |
                    BINARY_FLOAT | BINARY_DOUBLE ] ]
SQL> variable b3  RAW(18);
Usage: VAR[IABLE] [ <variable> [ NUMBER | CHAR | CHAR (n [CHAR|BYTE]) |
                    VARCHAR2 (n [CHAR|BYTE]) | NCHAR | NCHAR (n) |
                    NVARCHAR2 (n) | CLOB | NCLOB | REFCURSOR |
                    BINARY_FLOAT | BINARY_DOUBLE ] ]
--now the actual query below
SQL> SELECT * FROM TEST WHERE ID1=:B1 AND ID2 BETWEEN :B2 AND :B3;
SP2-0552: Bind variable "B3" not declared.
(this fails due to the errors earlier)Also this is a third party app schema so that we don't have the option of modifying the data type of the columns.
Thanks,
Edited by: orausern on May 10, 2011 11:30 AM

Try anonymous PL/SQL block:
declare
b1 RAW(18);
b2 RAW(18);
b3 RAW(18);
begin
b1:=..;
b2:=..;
b3:=..;
SELECT col1, col2, ..
INTO ...
FROM TEST
WHERE ID1=:B1
AND ID2 BETWEEN :B2 AND :B3;
end;
/

Similar Messages

  • SQL query with Bind variable with slower execution plan

    I have a 'normal' sql select-insert statement (not using bind variable) and it yields the following execution plan:-
    Execution Plan
    0 INSERT STATEMENT Optimizer=CHOOSE (Cost=7 Card=1 Bytes=148)
    1 0 HASH JOIN (Cost=7 Card=1 Bytes=148)
    2 1 TABLE ACCESS (BY INDEX ROWID) OF 'TABLEA' (Cost=4 Card=1 Bytes=100)
    3 2 INDEX (RANGE SCAN) OF 'TABLEA_IDX_2' (NON-UNIQUE) (Cost=3 Card=1)
    4 1 INDEX (FAST FULL SCAN) OF 'TABLEB_IDX_003' (NON-UNIQUE)
    (Cost=2 Card=135 Bytes=6480)
    Statistics
    0 recursive calls
    18 db block gets
    15558 consistent gets
    47 physical reads
    9896 redo size
    423 bytes sent via SQL*Net to client
    1095 bytes received via SQL*Net from client
    3 SQL*Net roundtrips to/from client
    1 sorts (memory)
    0 sorts (disk)
    55 rows processed
    I have the same query but instead running using bind variable (I test it with both oracle form and SQL*plus), it takes considerably longer with a different execution plan:-
    Execution Plan
    0 INSERT STATEMENT Optimizer=CHOOSE (Cost=407 Card=1 Bytes=148)
    1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TABLEA' (Cost=3 Card=1 Bytes=100)
    2 1 NESTED LOOPS (Cost=407 Card=1 Bytes=148)
    3 2 INDEX (FAST FULL SCAN) OF TABLEB_IDX_003' (NON-UNIQUE) (Cost=2 Card=135 Bytes=6480)
    4 2 INDEX (RANGE SCAN) OF 'TABLEA_IDX_2' (NON-UNIQUE) (Cost=2 Card=1)
    Statistics
    0 recursive calls
    12 db block gets
    3003199 consistent gets
    54 physical reads
    9448 redo size
    423 bytes sent via SQL*Net to client
    1258 bytes received via SQL*Net from client
    3 SQL*Net roundtrips to/from client
    1 sorts (memory)
    0 sorts (disk)
    55 rows processed
    TABLEA has around 3million record while TABLEB has 300 records. Is there anyway I can improve the speed of the sql query with bind variable? I have DBA Access to the database
    Regards
    Ivan

    Many thanks for your reply.
    I have run the statistic already for the both tableA and tableB as well all the indexes associated with both table (using dbms_stats, I am on 9i db ) but not the indexed columns.
    for table I use:-
    begin
    dbms_stats.gather_table_stats(ownname=> 'IVAN', tabname=> 'TABLEA', partname=> NULL);
    end;
    for index I use:-
    begin
    dbms_stats.gather_index_stats(ownname=> 'IVAN', indname=> 'TABLEB_IDX_003', partname=> NULL);
    end;
    Is it possible to show me a sample of how to collect statisc for INDEX columns stats?
    regards
    Ivan

  • Using collections / Bind variables with a PL/SQL functio returning a query

    I have this code, which is supposed to assign collection variables as column names
    FOR i in 1 .. Collection_count -1
    LOOP
    SELECT c002 into :P341_M1 FROM APEX_collections WHERE collection_name = 'MA_SKILLS' AND seq_id=i;
    SELECT c002 into varholder FROM APEX_collections WHERE collection_name = 'MA_SKILLS' AND seq_id=i;
    vQuery:= vQuery || 'SUM(decode(label, ''Aware'', product_'|| i || ', ''Expert'', product_' || i || ', ''Proficient'', product_' || i || ', ''Advanced(Demo)'', product_' || i || ' )) as ';
    vQuery:=vQuery || varholder || ', ' ;
    END LOOP;
    I've tried &P341_M1. , :P341_M1, ':P341_M1', varholder
    When I try '&P341_M1' it returns the whole SUM(decode... line as the label
    Basically Im having a hard time using bind variables with the PL/SQL returning a query...anybody?

    Ok so working through this problem more I have realized that the problem is using the for loop i as an index value
    This will get a value:
    SELECT c002 into :P341_M1 FROM APEX_collections WHERE collection_name = 'MA_SKILLS' AND seq_id=2;
    But this won't
    SELECT c002 into :P341_M1 FROM APEX_collections WHERE collection_name = 'MA_SKILLS' AND seq_id=i;
    I'm in the for loop, and use the i variable in other places within this loop...Is there a reason why I can't compare seq_id to i?
    My new code as follows:
    FOR i in 1 .. Collection_count -1 --apex_application.g_f01.COUNT - 1
    LOOP
    varholder:=i;
    SELECT c002 into :P341_M1 FROM APEX_collections WHERE collection_name = 'MA_SKILLS' AND seq_id=2;
    SELECT c002 into varholder FROM APEX_collections WHERE collection_name = 'MA_SKILLS' AND seq_id=4;
    vQuery:= vQuery || 'SUM(decode(label, ''Aware'', product_'|| i || ', ''Expert'', product_' || i || ', ''Proficient'', product_' || i || ', ''Advanced(Demo)'', product_' || i || ' )) as f';
    vQuery:=vQuery || :P341_M1 ||i||', ' ;
    END LOOP;

  • Query with bind variable, how can use it in managed bean ?

    Hi
    I create query with bind variable (BindControlTextValue), this query return description of value that i set in BindControlTextValue variable, how can i use this query in managed bean? I need to set this value in String parameter in managed bean.
    Thanks

    Put the query in a VO and execute it the usual way.
    If you need to, you can write a parameterized method in VOImpl that executes the VO query with the parameter and then call that method from the UI (as a methodAction binding) either through the managed bean or via a direct button click on the page.

  • Create collection from query with bind variable

    Apex 4.0.2
    Per Joel Re: Collection with bind variable the apex_collection.create_collection_from_query_b supports queries containing bind variable references (:P1_X) but I am not sure how to use this feature, the documentation doesn't have an example, just the API signature for the overloaded version has changed.
    If the query contains 2 bind variable references to session state (:P1_X and :P1_Y), can someone please show an example of what to pass in for the p_names and p_values parameters to the API?
    Thanks
    procedure create_collection_from_query_b(
        -- Create a named collection from the supplied query using bulk operations.  The query will
        -- be parsed as the application owner.  If a collection exists with the same name for the current
        -- user in the same session for the current Flow ID, an application error will be raised.
        -- This procedure uses bulk dynamic SQL to perform the fetch and insert operations into the named
        -- collection.  Two limitations are imposed by this procedure:
        --   1) The MD5 checksum for the member data will not be computed
        --   2) No column value in query p_query can exceed 2,000 bytes
        -- Arguments:
        --     p_collection_name   =  Name of collection.  Maximum length can be
        --                            255 bytes.  Note that collection_names are case-insensitive,
        --                            as the collection name will be converted to upper case
        --     p_query             =  Query to be executed which will populate the members of the
        --                            collection.  If p_query is numeric, it is assumed to be
        --                            a DBMS_SQL cursor.
        -- example(s):
        --     l_query := 'select make, model, caliber from firearms';
        --     apex_collection.create_collection_from_query_b( p_collection_name => 'Firearm', p_query => l_query );
        p_collection_name in varchar2,
        p_query           in varchar2,
        p_names           in wwv_flow_global.vc_arr2,
        p_values          in wwv_flow_global.vc_arr2,
        p_max_row_count   in number default null)
        ;

    VANJ wrote:
    Apex 4.0.2
    Per Joel Re: Collection with bind variable the apex_collection.create_collection_from_query_b supports queries containing bind variable references (:P1_X) but I am not sure how to use this feature, the documentation doesn't have an example, just the API signature for the overloaded version has changed.
    If the query contains 2 bind variable references to session state (:P1_X and :P1_Y), can someone please show an example of what to pass in for the p_names and p_values parameters to the API?Not tried it, but guessing something like
    apex_collection.create_collection_from_query_b(
        p_collection_name => 'foobar'
      , p_query => 'select f.foo_id, b.bar_id, b.baz from foo f, bar b where f.foo_id = b.foo_id and f.x = to_number(:p1_x) and b.y = :p1_y'
      , p_names => apex_util.string_to_table('p1_x:p1_y')
      , p_values => apex_util.string_to_table(v('p1_x') || ':' || v('p1_y')))

  • Report Query returning "No Data Found" with bind variables

    I put a simple query into Report Query:
    Select "bluefish". "name" as "name",
    "bluefish"."primary_flag" as "primary_flag",
    "bluefish"."status" as "status",
    "bluefish"."ID" as "ID" from "bluefish" "bluefish" where "bluefish"."ID" = :P3_XPRINTID
    When I test the query, data is returned; however, when I try to run the query using "Test Report" button, I get an error 01403 No Data Found. If I replace the bind variable with an explicit value, the report works.
    Anyone have any ideas as to what is causing this problem? I am using the Generic Report Layout, with various output types. I AM editting the query and defining the bind variable before I test the report (otherwise, the query wouldn't run).
    Charles

    Sometimes if you create a form/report/whatever using the wizards, it will create an After Submit process called something like Reset Page - basically you want to make sure you don't have any After Submit processes that call a Clear Session state (it may say something like Clear Cache for Page).
    In your branch, there is also a box that says Clear Cache - you want to make sure that does not have page Number 8 in it or it will clear your session state.
    Put the page in Debug mode and read through it - check to make sure your value is getting saved and maybe you can see what is going wrong.

  • Using bind variable with IN clause

    My application runs a limited number of straight up queries (no stored procs) using ODP.NET. For the most part, I'm able to use bind variables to help with query caching, etc... but I'm at a loss as to how to use bind variables with IN clauses. Basically, I'm looking for something like this:
    int objectId = 123;
    string[] listOfValues = { "a", "b", "c"};
    OracleCommand command = new OracleCommand();
    command.Connection = conn;
    command.BindByName = true;
    command.CommandText = @"select blah from mytable where objectId = :objectId and somevalue in (:listOfValues)";
    command.Parameters.Add("objectId", objectId);
    command.Parameters.Add("listOfValues", listOfValues);
    I haven't had much luck yet using an array as a bind variable. Do I need to pass it in as a PL/SQL associative array? Cast the values to a TABLE?
    Thanks,
    Nick

    Nevermind, found this
    How to use OracleParameter whith the IN Operator of select statement
    which contained this, which is a brilliant solution
    http://oradim.blogspot.com/2007/12/dynamically-creating-variable-in-list.html

  • How to use bind variables with XMLTABLE?

    I tried to use bind variables with xmltable statment. Here, my testcase:
    create or replace function wsdltest return xmltype as
    l_dummy xmltype;
    l_stt clob;
    l_name varchar2(500);
    l_xml clob;
    BEGIN
    l_xml :=
    '<definitions name="F1" targetNamespace="http://xmlns.oracle.com/orawsv/XFILES/F1" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://xmlns.oracle.com/orawsv/XFILES/F1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
    <types>
    <xsd:schema targetNamespace="http://xmlns.oracle.com/orawsv/XFILES/F1" elementFormDefault="qualified">
    <xsd:element name="SVARCHAR2-F1Input">
    <xsd:complexType>
    <xsd:sequence>
    <xsd:element name="A-VARCHAR2-IN" type="xsd:string"/>
    </xsd:sequence>
    </xsd:complexType>
    </xsd:element>
    <xsd:element name="F1Output">
    <xsd:complexType>
    <xsd:sequence>
    <xsd:element name="RETURN" type="xsd:string"/>
    </xsd:sequence>
    </xsd:complexType>
    </xsd:element>
    </xsd:schema>
    </types>
    <message name="F1InputMessage">
    <part name="parameters" element="tns:SVARCHAR2-F1Input"/>
    </message>
    <message name="F1OutputMessage">
    <part name="parameters" element="tns:F1Output"/>
    </message>
    <portType name="F1PortType">
    <operation name="F1">
    <input message="tns:F1InputMessage"/>
    <output message="tns:F1OutputMessage"/>
    </operation>
    </portType>
    <binding name="F1Binding" type="tns:F1PortType">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="F1">
    <soap:operation soapAction="F1"/>
    <input>
    <soap:body parts="parameters" use="literal"/>
    </input>
    <output>
    <soap:body parts="parameters" use="literal"/>
    </output>
    </operation>
    </binding>
    <service name="F1Service">
    <documentation>Oracle Web Service</documentation>
    <port name="F1Port" binding="tns:F1Binding">
    <soap:address location="http://localhost:8080/orawsv/XFILES/F1"/>
    </port>
    </service>
    </definitions>';
    -- OK
    l_stt := 'select * from xmltable(XMLNAMESPACES(''http://www.w3.org/2001/XMLSchema'' AS "XSD", default ''http://schemas.xmlsoap.org/wsdl/''),
    ''//definitions/types/XSD:schema/XSD:element[@name="SVARCHAR2-F1Input"]''
    passing xmltype(:1)
    columns
    ab xmltype path ''.'' ) t';
    EXECUTE IMMEDIATE l_stt INTO l_dummy using l_xml;
    -- ERROR ORA-01006
    l_name := '"SVARCHAR2-F1Input"';
    l_stt := 'select * from xmltable(XMLNAMESPACES(''http://www.w3.org/2001/XMLSchema'' AS "XSD", default ''http://schemas.xmlsoap.org/wsdl/''),
    ''//definitions/types/XSD:schema/XSD:element[@name=:2]''
    passing xmltype(:1)
    columns
    ab xmltype path ''.'' ) t';
    EXECUTE IMMEDIATE l_stt INTO l_dummy using l_xml, l_name;
    return l_dummy;
    END;
    Any idea ?
    Thanks in advance
    Cyryl

    Why are you using dynamic SQL statements? Why not just use something like this instead in your PL/SQL. I also replaced the leading // in your Xpath with just / since you start from the root node.
    select *
      INTO l_dummy
      from xmltable(XMLNAMESPACES('http://www.w3.org/2001/XMLSchema' AS "XSD", default 'http://schemas.xmlsoap.org/wsdl/'),
                    '/definitions/types/XSD:schema/XSD:element'
                    passing xmltype(l_xml)
                    columns
                    ab xmltype path '.' ) t;Also, the above returns two rows, which I suspect is not what you want. Here is the pure SQL version for you to debug.
    select *
      from xmltable(XMLNAMESPACES('http://www.w3.org/2001/XMLSchema' AS "XSD", default 'http://schemas.xmlsoap.org/wsdl/'),
                   '/definitions/types/XSD:schema/XSD:element'
                   passing xmltype('<definitions name="F1" targetNamespace="http://xmlns.oracle.com/orawsv/XFILES/F1" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://xmlns.oracle.com/orawsv/XFILES/F1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
    <types>
    <xsd:schema targetNamespace="http://xmlns.oracle.com/orawsv/XFILES/F1" elementFormDefault="qualified">
    <xsd:element name="SVARCHAR2-F1Input">
    <xsd:complexType>
    <xsd:sequence>
    <xsd:element name="A-VARCHAR2-IN" type="xsd:string"/>
    </xsd:sequence>
    </xsd:complexType>
    </xsd:element>
    <xsd:element name="F1Output">
    <xsd:complexType>
    <xsd:sequence>
    <xsd:element name="RETURN" type="xsd:string"/>
    </xsd:sequence>
    </xsd:complexType>
    </xsd:element>
    </xsd:schema>
    </types>
    <message name="F1InputMessage">
    <part name="parameters" element="tns:SVARCHAR2-F1Input"/>
    </message>
    <message name="F1OutputMessage">
    <part name="parameters" element="tns:F1Output"/>
    </message>
    <portType name="F1PortType">
    <operation name="F1">
    <input message="tns:F1InputMessage"/>
    <output message="tns:F1OutputMessage"/>
    </operation>
    </portType>
    <binding name="F1Binding" type="tns:F1PortType">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="F1">
    <soap:operation soapAction="F1"/>
    <input>
    <soap:body parts="parameters" use="literal"/>
    </input>
    <output>
    <soap:body parts="parameters" use="literal"/>
    </output>
    </operation>
    </binding>
    <service name="F1Service">
    <documentation>Oracle Web Service</documentation>
    <port name="F1Port" binding="tns:F1Binding">
    <soap:address location="http://localhost:8080/orawsv/XFILES/F1"/>
    </port>
    </service>
    </definitions>'
                   columns
                   ab xmltype path '.' ) t

  • Af:query with bind variables and Saved Search

    I have a VO and view criteria(VC).
    VC has a criteria item ObsoleteDate with range specified as bindVariables "dateFrm" and "dateTo" I dragged & dropped the named criteria as af:Query with table. Table toolbar has 2 buttons in which I set & clear the bind variables. Data is fetched as per as expected based on the VC & bind variables.
    The problem is,
    If I save my search with bind variables set and swap between the saved searches , all works fine. But the moment I clear bind variables & swap between searches.. "dateFrm" is populated and "dateTo" is null and I get an Exception oracle.jbo.AttrValException: JBO-27035: Attribute Obsolete Date: is required.
    Why is this happening?? Saved search is supposed to save the VC with all the bind values set while saving and clearing bind variables shouldn't affect the saved search, right?? Or I have understood it wrong?
    I am using JDeveloper 11.1.2.3.0
    Thanks

    Try
    like ? || '%'

  • How to add '%' to a query with bind variables

    Hi,
    I am using oracle jdeveloper 11g.
    I am trying to create a table to display rows using the below query in a jspx page,
    select * from ade_txns where series='WORKPLACE_PT.11.1.1.8.0_GENERIC' and transaction like 'rkumara%'
    I am using a view with query and binding variables as below,
    select * from ade_txns where series= :p_series and transaction like :p_QAEngineer
    I will be passing p_QAEngineer using binding variable using 'ExecuteWithParams' using a dropdown(eg: 'rkumara'). But I need to add a '%' to this value as I am using a 'LIKE' clause in my query.
    I tried using,
    select * from ade_txns where series= :p_series and transaction like :p_QAEngineer+'%'
    But this is not working for me.
    Can someone please tell me how i can solve this.
    Thanks,
    Ranjeet

    does this help also?
    How to add regular expression in viewobject bind variables
    ~Abhijit

  • Slow Query over Database Link with Bind Variable

    I have a query over a DB link, with all tables on the remote database.
    If I use a bind variable (from Toad), the query takes 4 minutes. If I replace the bind variable with a constant or substitution variable, it takes 1 second.
    The query runs fine when run directly on the remote database using bind variable.
    9.2.0.7

    Look up "Bind variable peeking"
    What's happened is you have an execution plan that differs from the one with the constant. Why? My bet is that Oracle "peeked" at the bind variable to help it decide which execution plan to build. It then cached it. It probably cached an execution with an index when it should be doing a full table scan or a hash join instead of a nested loop. It's hard to say specifically what it is.
    Try this, flush your shared pool and rerun the query with the bind and let us know if it takes 1 second or 4 minutes. If it takes 1 second, then that was probably it.
    Read part 2 of Tom Kyte's blog post on what it is and it's behavior.
    http://tkyte.blogspot.com/2007/09/sqltracetrue-part-two.html

  • How to use ApplicationModuleImpl.createViewObject for VO with bind variable

    I need to implement a AM method to create VO instance from a generic VODef with bind variables.
    The createViewObject() will trigger the executeQuery of the VO before I can set up the bind variables for the query.
    What is the proper way to create view object instance with bind variables?

    I am using JDeveloper 11.1.1.2.
    I have a ViewObjectA declared with some bind variables which determine what business data to be retrieved at runtime via a service method of the ApplicationModule.
    As the ViewObjectA is only referenced internally within ApplicationModule and I need more than one instance of the ViewObjectA for different conditions at runtime,
    I use ApplicationModuleImpl.createViewObject() to create an instance of ViewObjectA instead of adding ViewObjectA to the data model of the ApplicationModule.
    Currently, when the ViewObjectA is instantiated, it also trigger an executeQuery() which will not retrieve correct data until I set up the bind variables.
    However, the createViewObject() method doesn't let me pass in the values of the binding variables.
    Currenlty, I just call the createViewObject() and then set the binding variables values and call executeQuery() again.
    Just checking if there is a better way to do so...

  • ODT Query Window. Query with binding variable?

    I have the ODT 11.1.0.7.20 installed.
    In "Query Window", I execute an SQL with binding variables. But I only get ORA-01008 errors. How do I do that?
    I want to double click an SQL and load it in "Query Window". How do I do that?
    I want to right click an SQL and select "Open with Query Window". How do I do that?
    In Query Window I want to load an SQL either by drag and drop or by select a function "Open SQL". How do I do that?
    Why none of these functionalities work as you could expect?
    Thanks,
    Tobias

    Finally i found the problem..
    The problem was that i had to remove one line from the properties of my table departments, the property: selectedrowkeys, because it only passed the last selected row.
    Still, i apreciate the help and i had to replace some code in the bean.java , because of the exception error and you didn't had to do that. Maybe i did some configuration in the wrong way and it went wrong.
    Thanks for the help.
    Regards,
    Frederico.

  • Report Performance with Bind Variable

    Getting some very odd behaviour with a report in APEX v 3.2.1.00.10
    I have a complex query that takes 5 seconds to return via TOAD, but takes from 5 to 10 minutes in an APEX report.
    I've narrowed it down to one particular bind. If I hard code the date in it returns in 6 seconds, but if I let the date be passed in from a parameter it takes 5+ minutes again.
    Relevant part of the query (an inline view) is:
    ,(select rglr_lect lect
    ,sum(tpm) mtr_tpm
    ,sum(enrols) mtr_enrols
    from ops_dash_meetings_report
    where meet_ev_date between to_date(:P35_END_DATE,'DD/MM/YYYY') - 363 and to_date(:P35_END_DATE,'DD/MM/YYYY')
    group by rglr_lect) RPV
    I've tried replacing the "to_date(:P35_END_DATE,'DD/MM/YYYY') - 363" with another item which is populated with the date required (and verified by checking session state). If I replace the :P35_END_DATE with an actual date the performance is fine again.
    The weird thing is that a trace file shows me exactly the same Explain Plan as the TOAD Explain where it runs in 5 seconds.
    Another odd thing is that another page in my application has the same inline view and doesn't hit the performance problem.
    The trace file did show some control characters (circumflex M) after each line of this report's query where these weren't anywhere else on the trace queries. I wondered if there was some sort of corruption in the source?
    No problems due to pagination as the result set is only 31 records and all being displayed.
    Really stumped here. Any advice or pointers would be most welcome.
    Jon.

    Don't worry about the Time column, the cost and cardinality are more important to see whther the CBO is making different decisions for whatever reason.
    Remember that the explain plan shows the expected execution plan and a trace shows the actual execution plan. So what you want to do is compare the query with bind variables from an APEX page trace to a trace from TOAD (or sqlplus or whatever). You can do this outside APEX like this...
    ALTER SESSION SET EVENTS '10046 trace name context forever, level 1';Enter and run your SQL statement...;
    ALTER SESSION SET sql_trace=FALSE;This will create a a trace file in the directory returned by...
    SELECT value FROM v$parameter WHERE name = 'user_dump_dest' Which you can use tkprof to format.
    I am assuming that your not going over DB links or anything else slightly unusual?
    Cheers
    Ben

  • SLOW report performance with bind variable

    Environment: 11.1.0.7.2, Apex 4.01.
    I've got a simplified report page where the report runs slowly compared to running the same query in sqldeveloper. The report region is based on a pl/sql function returning a query. If I use a bind variable in the query inside apex it takes 13 seconds to run, and if I hard code a string it takes only a few hundredths of a second. The query returns one row from a table which has 1.6 million rows. Statistics are up-to-date and the columns in the joins and where clause are indexed.
    I've run traces using p_trace=YES from Apex for both the bind variable and hard coded strings. They are below.
    The sqldeveloper explain plan is identical to the bind variable plan from the trace, yet the query runs in 0.0x seconds in sqldeveloper.
    What is it about bind variable syntax in Apex that is causing the bad execution plan? Apex Bug? 11g bug? Ideas?
    tkprof output from Apex trace with bind variable is below...
    select p.master_id link, p.first_name||' '||p.middle_name||' '||p.last_name||' '||p.suffix personname,
    p.gender||' '||p.date_of_birth g_dob, p.master_id||'*****'||substr(p.ssn,-4) ssn, p.status status
    from persons p
    where
       p.person_id in (select ps.person_id from person_systems ps where ps.source_key  like  LTRIM(RTRIM(:P71_SEARCH_SOURCE1)))
    order by 1
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.00       0.00          0          0          0           0
    Execute      1      0.00       0.01          0          1         27           0
    Fetch        2     13.15      13.22      67694      72865          0           1
    total        4     13.15      13.23      67694      72866         27           1
    Misses in library cache during parse: 0
    Optimizer mode: ALL_ROWS
    Parsing user id: 62  (ODPS_PRIVACYVAULT)   (recursive depth: 1)
    Rows     Row Source Operation
          1  SORT ORDER BY (cr=72869 pr=67694 pw=0 time=0 us cost=29615 size=14255040 card=178188)
          1   FILTER  (cr=72869 pr=67694 pw=0 time=0 us)
          1    HASH JOIN RIGHT SEMI (cr=72865 pr=67694 pw=0 time=0 us cost=26308 size=14255040 card=178188)
          1     INDEX FAST FULL SCAN IDX$$_0A300001 (cr=18545 pr=13379 pw=0 time=0 us cost=4993 size=2937776 card=183611)(object id 68485)
    1696485     TABLE ACCESS FULL PERSONS (cr=54320 pr=54315 pw=0 time=21965 us cost=14958 size=108575040 card=1696485)
    Rows     Execution Plan
          0  SELECT STATEMENT   MODE: ALL_ROWS
          1   SORT (ORDER BY)
          1    FILTER
          1     HASH JOIN (RIGHT SEMI)
          1      INDEX   MODE: ANALYZED (FAST FULL SCAN) OF
                     'IDX$$_0A300001' (INDEX)
    1696485      TABLE ACCESS   MODE: ANALYZED (FULL) OF 'PERSONS' (TABLE)
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      db file scattered read                       1276        0.00          0.16
      db file sequential read                       812        0.00          0.02
      direct path read                             1552        0.00          0.61
    ********************************************************************************Here's the tkprof output with a hard coded string:
    select p.master_id link, p.first_name||' '||p.middle_name||' '||p.last_name||' '||p.suffix personname,
    p.gender||' '||p.date_of_birth g_dob, p.master_id||'*****'||substr(p.ssn,-4) ssn, p.status status
    from persons p
    where
       p.person_id in (select ps.person_id from person_systems ps where ps.source_key  like  LTRIM(RTRIM('0b')))
    order by 1
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.02       0.04          0          0          0           0
    Execute      1      0.00       0.00          0          0         13           0
    Fetch        2      0.00       0.00          0          8          0           1
    total        4      0.02       0.04          0          8         13           1
    Misses in library cache during parse: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 62  (ODPS_PRIVACYVAULT)   (recursive depth: 1)
    Rows     Row Source Operation
          1  SORT ORDER BY (cr=10 pr=0 pw=0 time=0 us cost=9 size=80 card=1)
          1   FILTER  (cr=10 pr=0 pw=0 time=0 us)
          1    NESTED LOOPS  (cr=8 pr=0 pw=0 time=0 us)
          1     NESTED LOOPS  (cr=7 pr=0 pw=0 time=0 us cost=8 size=80 card=1)
          1      SORT UNIQUE (cr=4 pr=0 pw=0 time=0 us cost=5 size=16 card=1)
          1       TABLE ACCESS BY INDEX ROWID PERSON_SYSTEMS (cr=4 pr=0 pw=0 time=0 us cost=5 size=16 card=1)
          1        INDEX RANGE SCAN IDX_PERSON_SYSTEMS_SOURCE_KEY (cr=3 pr=0 pw=0 time=0 us cost=3 size=0 card=1)(object id 68561)
          1      INDEX UNIQUE SCAN PK_PERSONS (cr=3 pr=0 pw=0 time=0 us cost=1 size=0 card=1)(object id 68506)
          1     TABLE ACCESS BY INDEX ROWID PERSONS (cr=1 pr=0 pw=0 time=0 us cost=2 size=64 card=1)
    Rows     Execution Plan
          0  SELECT STATEMENT   MODE: ALL_ROWS
          1   SORT (ORDER BY)
          1    FILTER
          1     NESTED LOOPS
          1      NESTED LOOPS
          1       SORT (UNIQUE)
          1        TABLE ACCESS   MODE: ANALYZED (BY INDEX ROWID) OF
                       'PERSON_SYSTEMS' (TABLE)
          1         INDEX   MODE: ANALYZED (RANGE SCAN) OF
                        'IDX_PERSON_SYSTEMS_SOURCE_KEY' (INDEX)
          1       INDEX   MODE: ANALYZED (UNIQUE SCAN) OF 'PK_PERSONS'
                      (INDEX (UNIQUE))
          1      TABLE ACCESS   MODE: ANALYZED (BY INDEX ROWID) OF
                     'PERSONS' (TABLE)

    Patrick, interesting insight. Thank you.
    The optimizer must be peeking at my bind variables with it's eyes closed. I'm the only one testing and I've never passed %anything as a bind value. :)
    Here's what I've learned since my last post:
    I don't think that sqldeveloper is actually using the explain plan it says it is. When I run explain plan in sqldeveloper (with a bind variable) it shows me the exact same plan as Apex with a bind variable. However, when I run autotrace in sqldeveloper, it takes a path that matches the hard coded values, and returns results in half a second. That autotrace run is consistent with actually running the query outside of autotrace. So, I think either sqldeveloper isn't really using bind variables, OR it is using them in some other way that Apex does not, or maybe optimizer peeking works in sqldeveloper?
    Using optimizer hints to tweak the plan helps. I've tried both /*+ FIRST_ROWS */ and /*+ index(ps pk_persons) */ and both drop the query to about a second. However, I'm loath to use hints because of the very dynamic nature of the query (and Tom Kyte doesn't like them either). The hints may end up hurting other variations on the query.
    I also tested the query by wrapping it in a select count(1) from ([long query]) and testing the performance in sqldeveloper and in Apex. The performance in that case is identical with both bind variables and hard coded variables for both Apex and SqlDeveloper. That to me was very interesting and I went so far as to set up two bind variable report regions on the same page. One region wrapped the long query with select count(1) from (...) and the other didn't. The wrapped query ran in 0.01 seconds, the unwrapped took 15ish seconds with no other optimizations. Very strange.
    To get performance up to acceptable levels I have changed my function returning query to:
    1) Set the equality operator to "=" for values without wildcards and "like" for user input with wildcards. This makes a HUGE difference IF no wildcard is used.
    2) Insert a /*+ FIRST_ROWS */ hint when users chose the column that requires the sub-query. This obviously changes the optimizer's plan and improves query speed from 15 seconds to 1.5 seconds even with wildcards.
    I will NOT be hard coding any user supplied values in the query string. As you can probably tell by the query, this is an application where sql injection would be very bad.
    Jeff, regarding your question about "like '%' || :P71_SEARCH_SOURCE1 || '%'". I've found that putting wildcards around values, particularly at the beginning will negate any indexing on the column in question and slows performance even more.
    I'm still left wondering if there isn't something in Apex that is breaking the optimizer "peeking" that Patrick describes. Perhaps something in the way it switches contexts from apex_public_user to the workspace schema?

Maybe you are looking for