Running explain plan on a prepared statement

I'm using IBatis to run queries against an Oracle database. IBatis runs the queries as prepared statements. I want to run explain plan on the prepared statements.
I already have a shim -- a proxy java.sql.Connection object -- that takes the SQL used to create a prepared statement (e.g., "select a, b, c from table d where c = ?"), returns a proxy java.sql.PreparedStatement, and then on the PreparedStatement's execute(), interpolates the bound parameters into the SQL statement, and runs Explain Plan on that (e.g, preparedStatement.setInt(5) is called, followed by preparedStatement.execute(), which results in my proxy running "explain plan for select a, b, c from table d where c = 5;")
Using Spring configuration, I can transparently insert the shim and get explain plans for all queries run through that Connection.
The problem is this: I'm explaining the plan for the SQL with the bound parameters, not necessarily the SQL run for the prepared statement.
Assume that in the above example, there exists an index on column c in table d, and that 5% of d's rows have the value 1, 15% have the value 2, and 80% have the value 3.
For "select a, b, c from table d where c = 1", Oracle will use the index. But for "select a, b, c from table d where c = 3", Oracle will do a full table scan.
What I want to know is what Oracle will do for "select a, b, c from table d where c = ?" when "?" is an unknown, arbitrary value subsequently bound to 1 or to 3.
As I understand it, the query plan for a prepared statement is done once, when the prepared statement is created. At execute time (as I understand it), the query plan is not reformulated based on the actual bound values (though partition pruning is recalculated).
So how can I find out what query plan is actually be used for prepred statement?
Thanks.

I already have a shim -- a proxy java.sql.Connection object -- that takes the SQL used to create a prepared statement I believe explain plan is part of PL/SQL rather than external to it.
As such you can pass it via a prepared statement. It is just a matter of getting the syntax correct. And of course collecting the result.
The syntax is going to be be something like the following. You would use it just like you use the existing sql.
begin
   select ... from ... where c = ?;
endThe result might be returned a result sets (plural). If so you would need to code appropriately for that.

Similar Messages

  • How to run Explain Plan for SP?

    Can we run Explain Plan for SP??

    EXPLAIN PLAN creates an execution plan for SQL statements. PL/SQL is not SQL.
    PL/SQL procedures can contain SQL, yes. These SQLs can be copied and pasted from PL/SQL into something like TOAD and execution plan determined.
    However, if the aim is to see the "execution/performance plan" for PL/SQL code, then you need to profile the PL/SQL code using the DBMS_PROFILER package. This will tell you the execution path and elapsed time to execute a line of PL/SQL.
    Details can be found in the [url http://download-east.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_profil.htm#sthref5502]Oracle® Database PL/SQL Packages and Types Reference guide.

  • What are the permissions needed to run explain plans via sql develeper?

    Are the permissions the same in Sql Developer to run explain plans like they are when you run them via sql*plus?

    Yes same permission because the explain plan does not tie to the tools.

  • Question about running explain plan

    I tried to run explain plan for a simple query, just to familiarize myself with how to do it. (I have another query that's taking a long time, and I've never run explain plan before). I got an error, googled it, and discovered I had to run the file at @%ORACLE_HOME%\rdbms\admin\utlxplan.sql first, to create the Plan_Table. Well, I tried to run that file and I get the error that I don't have priveleges on the tablespace. This really doesn't surprise me, as my access is read-only. Is there any way around this? I don't know a whole lot about databases, so forgive me if these following questions are dumb, but...
    1) is that file basically trying to create a table (called Plan_Table) within the schema I'm in (the only schema I have access to)?
    2) can my company's DBA run that file for me to create the Plan_Table?

    What version of the database are you on?
    You can get run-time execution plans from V$SQL_PLAN. You will need permission to read the V$ views. First find your query in V$SQL_PLAN (you can do a text search; putting a comment in like '--my_query' can help), then join to V$SQL_PLAN to find the query plan that that query used - join by the ADDRESS and HASH_VALUE columns.
    Otherwise, see if you can get insert/update/delete access on just that one table when your DBA creates it
    Good luck.

  • Explain plan different with no stats but with no rows & rows in a table

    Hi All,
    This is in Oracle 8.1.7.4.0 DB.
    1. Query was taking long time to return rows. It was based on a view.
    2. View has multiple tables.
    3. The explain plan was showing one of the Table(e.g. TABLE1) using incorrect INDEX. At the time of explain plan table has no statistics.
    4. truncated Table TABLE1
    5. The explain plan now taking correct INDEX for the table TABLE1.
    How does optimizer choosing the incorrect index when rows in a table & correct index when there are no rows in the table ?
    any insights.
    Thanks
    Sandeep

    I don't know about your particular db version, but CBO in absence of statistics uses some default values (e.g. average row length 100 bytes) and also uses actual number of block for the table. I assume something similar might be for indexes.
    To be sure what has changed you can run 10053 level trace.
    Gints Plivna
    http://www.gplivna.eu

  • ORA-01745 when running Explain Plan

    Hello everybody,
    I would like to know what is the best way to report a bug. In fact I believe just found one and I would like it fixed. I am using the latest version of SQLDeveloper on WinXP that uses its own JDK.
    To replicate the bug it's very easy, just try to do an explain plan of the following query:
    SELECT * FROM scott.emp
    where empno = &&emp_nr;and the "*ORA-01745: invalid host/bind variable name*" error appears. Since the query executes properly, but the Explain plan errors out, I believe this could be a bug.
    Thanks,
    Paolo

    Gary,
    thanks a lot for your feedback.
    I have found this weird behaviour, because I was trying to avoid another one. In fact I tried using the substitution variable syntax instead of the bind variable syntax in SQLDeveloper, especially to avoid the issues coming from automatic data conversions.
    For example, if I run the following query using the bind variable syntax (passing SYSDATE as the parameter value):
    SELECT *
       FROM scott.emp
      WHERE hiredate BETWEEN TRUNC(:p_eff_date,'yyyy')
                         AND TRUNC(add_months(:p_eff_date,12),'yyyy') - 1;it will go in error with "*ORA-00932: inconsistent datatypes: expected DATE got NUMBER*", because the filter predicate will be converted automatically as follows:
    TRUNC(TO_NUMBER(:P_EFF_DATE),TO_NUMBER('yyyy'))<=TRUNC(ADD_MONTHS(:P_EFF_DATE,12),'fmyyyy')-1This behaviour is visible by running the explain plan on the above query. Isn't that TO_NUMBER(:P_EFF_DATE),TO_NUMBER('yyyy') a little bit too wrong? Note that the second occurrence of the P_EFF_DATE parameter does not get converted. Can't this "automatic conversion" behaviour be disabled somehow?
    Due to this weird issue I tried to use the substitution variable syntax, but the main issue with the single ampersand is that you have to enter the value of the parameter as many times as the parameter is referenced in the query and you can imagine that with big queries written by other people this is not so easy.
    Is there another way to pass parameters to a query in the SQL Worksheet? How can I "use literals rather than variables" as you suggest? Do you mean NOT using parameters at all?
    Thanks,
    Paolo

  • Explain plan for a sql statement

    Hi,
    I have a simple sql statement which has a cost of 122, cardinality 59 and CPU cost 1966777.
    Same sql statement written in another way (using a nested select in the 'from' clause), has a cost of 58, cardinality 24 but cpu cost is much higher 29078895.
    What should I look for? For a better cost overall, or for a better cpu cost? Which statement should I consider? What is most important?
    Thanks.

    Roger25 wrote:
    ... Based on this, my question is what statement to choose? which is more important, the cost or the cpu cost?
    Thanks.
    Based on this, sorry, but my reply will remain unchanged:
    Again, you cannot compare explain plan of two different queries.
    Find out more:
    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:313416745628
    Nicolas.

  • Why tkprof did not show explain plan for some sql statements

    Hi,
    I did a trace for one of the session, hoping to find the explain plan for its tkprof. However, I only get this:
    INSERT INTO AUDIT_TABLE
    VALUES
    ( :B1 , :B2 , :B3 , :B4 , :B5 , :B6 , :B8 , :B7 )
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.00       0.00          0          0          0           0
    Execute   3698      8.08      59.41       3348        566      19092        3698
    Fetch        0      0.00       0.00          0          0          0           0
    total     3699      8.08      59.42       3348        566      19092        3698
    Misses in library cache during parse: 1
    Misses in library cache during execute: 1
    Optimizer mode: CHOOSE
    Parsing user id: 30     (recursive depth: 2)
    ********************************************************************************Any idea why the explain plan is missing?
    Also looking at the above statistics, what can I conclude?

    Thanks John. What's ur take on this statistics then?
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        0      0.00       0.00          0          0          0           0
    Execute   1798     12.23      36.75       1758       5404       7418        1798
    Fetch        0      0.00       0.00          0          0          0           0
    total     1798     12.23      36.75       1758       5404       7418        1798
    Misses in library cache during parse: 0
    Optimizer mode: CHOOSE
    Parsing user id: 30     (recursive depth: 1)
    ********************************************************************************

  • How does SQL Developer run EXPLAIN PLAN?

    Hello,
    I noticed that SQL Developer can do an EXPLAIN PLAN even though I don't have a PLAN_TABLE available for the user that I use to connect in SQL Developer.
    I was always wondering whether there was a way to do an EXPLAIN PLAN without a PLAN_TABLE, apparently this seems to be possible.
    Thomas

    If I try an explain plan when I do not have a plan table available, I get the message "A PLAN_TABLE is required to access the explain plan, but it does not exist. Do you want to create a PLAN_TABLE?". Unfortunately, as that user does not have create table privs, if I say Yes I get the following error "ORA-01031: insufficient privileges".
    Given this, if you are doing an explain plan, you either have access to a plan table or you have create table privs and SQL Developer has created the plan table for you.

  • Problems with explain plan and statement

    Hi community,
    I have migrated a j2ee application from DB2 to Oracle.
    First some facts of our application and database instance:
    We are using oracle version 10.2.0.3 and driver version 10.2.0.3. It runs with charset Unicode 3.0 UTF-8.
    Our application is using Tomcat as web container and jboss as application server. We are only using prepared statements. So if I talk about statements I always mean prepared statements. Also our application is setting the defaultNChar property to true because every char and varchar field has been created as an nchar and nvarchar.
    We have some jsp sites that contains lists with search forms. Everytime I enter a value to the form that returns a filled resultset, the lists are performing great. But everytime I enter a value that returns an empty resultset, the lists are 100 times slower. The jsp sites are running in the tomcat environment and submitting their statements directly to the database. The connections are pooled by dbcp. So what can cause this behaviour??
    To anaylze this problem I started logging all statements and filled-in search field values and combinations that are executed by the lists described above. I also developed a standalone helper tool that reads the logged statements, executes them to the database and generates an explain plan for every statement. But now there appears a strange situation. Every statement, that performs really fast within our application, is now executed by the helper tool extremely slow. So I edited some jsp pages within our application to force an explain plan from there (tomcat env). So when I'm executing the same statement I'm getting with the exactly same code two completely different explain plans.
    First the statement itself:
    select LINVIN.BBASE , INVINNUM , INVINNUMALT , LINVIN.LSUPPLIERNUM , LSUPPLIERNUMEXT , LINVIN.COMPANYCODE , ACCOUNT , INVINTXT , INVINSTS , INVINTYP , INVINDAT , RECEIPTDAT , POSTED , POSTINGDATE , CHECKCOSTCENTER , WORKFLOWIDEXT , INVINREFERENCE , RESPONSIBLEPERS , INVINSUM_V , INVINSUMGROSS_V , VOUCHERNUM , HASPOSITIONS , PROCESSINSTANCEID , FCURISO_V , LSUPPLIER.AADDRLINE1 from LINVIN, LSUPPLIER where LINVIN.BBASE = LSUPPLIER.BBASE and LINVIN.LSUPPLIERNUM = LSUPPLIER.LSUPPLIERNUM and LINVIN.BBASE = ? order by LINVIN.BBASE, INVINDAT DESC
    Now the explain plan from our application:
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 101 | 28583 | 55 (0)| 00:00:01 |
    | 1 | NESTED LOOPS | | 101 | 28583 | 55 (0)| 00:00:01 |
    | 2 | TABLE ACCESS BY INDEX ROWID| LINVIN | 93709 | 12M| 25 (0)| 00:00:01 |
    |* 3 | INDEX RANGE SCAN | LINV_INVDAT | 101 | | 1 (0)| 00:00:01 |
    | 4 | TABLE ACCESS BY INDEX ROWID| LSUPPLIER | 1 | 148 | 1 (0)| 00:00:01 |
    |* 5 | INDEX UNIQUE SCAN | PK_177597 | 1 | | 1 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    3 - access("LINVIN"."BBASE"=:1)
    filter("LINVIN"."BBASE"=:1)
    5 - access("LSUPPLIER"."BBASE"=:1 AND "LINVIN"."LSUPPLIERNUM"="LSUPPLIER"."LSUPPLIERNUM")
    Now the one from the standalone tool:
    | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 93773 | 25M| | 12898 (1)| 00:02:35 |
    | 1 | SORT ORDER BY | | 93773 | 25M| 61M| 12898 (1)| 00:02:35 |
    |* 2 | HASH JOIN | | 93773 | 25M| 2592K| 7185 (1)| 00:01:27 |
    | 3 | TABLE ACCESS BY INDEX ROWID| LSUPPLIER | 16540 | 2390K| | 332 (0)| 00:00:04 |
    |* 4 | INDEX RANGE SCAN | LSUPPLIER_HAS_BASE_FK | 16540 | | | 11 (0)| 00:00:01 |
    | 5 | TABLE ACCESS BY INDEX ROWID| LINVIN | 93709 | 12M| | 6073 (1)| 00:01:13 |
    |* 6 | INDEX RANGE SCAN | LINVOICE_BMDT_FK | 93709 | | | 84 (2)| 00:00:02 |
    Predicate Information (identified by operation id):
    2 - access("LINVIN"."BBASE"="LSUPPLIER"."BBASE" AND "LINVIN"."LSUPPLIERNUM"="LSUPPLIER"."LSUPPLIERNUM")
    4 - access("LSUPPLIER"."BBASE"=:1)
    6 - access("LINVIN"."BBASE"=:1)
    The size of the tables are: LINVIN - 383.692 Rows, LSUPPLIER - 115.782 Rows
    As you can see the one executed from our application is much faster than the one from the helper tool. So why picks oracle a completely different explain plan for the same statement? An why is a hash join much slower than a nested loop? Because If I'm right a nested loop should only be used when the tables are pretty small..
    I also tried to play with some parameters:
    I set optimizer_index_caching to 100 and optimizer_index_cost_adj to 30. I also changed optimizer_mode to FIRST_ROWS_100.
    I would really appreciated, if somebody can help me with this issue, because I'm really getting more and more distressed...
    Thanks in advance,
    Tobias
    Edited by: tobiwan on Sep 3, 2008 11:49 PM
    Edited by: tobiwan on Sep 3, 2008 11:50 PM
    Edited by: tobiwan on Sep 4, 2008 12:01 AM
    Edited by: tobiwan on Sep 4, 2008 12:02 AM
    Edited by: tobiwan on Sep 4, 2008 12:04 AM
    Edited by: tobiwan on Sep 4, 2008 12:06 AM
    Edited by: tobiwan on Sep 4, 2008 12:06 AM
    Edited by: tobiwan on Sep 4, 2008 12:07 AM

    tobiwan wrote:
    Hi again,
    Here ist the answer:
    The problem, because I got two different explain plans, was that the external tool uses the NLS sesssion parameters coming from the OS which are in my case "de/DE".
    Within our application these parameters are changed to "en/US"!! So if I'm calling in my external tool the java function Locale.setDefault(new Locale("en","US")) before connecting to the database the explain plans are finally equal.That might explain why you got two different execution plan, because one plan was obviously able to avoid a SORT ORDER BY operation, whereas the second plan required to run SORT ORDER BY operation, obviously because of the different NLS_SORT settings. An index by default uses the NLS_SORT = 'binary' order whereas ORDER BY obeys the NLS_SORT setting, which probably was set to 'GERMAN' in your "external tool" case. You can check the "NLS_SESSION_PARAMETERS" view to check your current NLS_SORT setting.
    For more information regarding this issue, see my blog note I've written about this some time ago:
    http://oracle-randolf.blogspot.com/2008/09/getting-first-rows-of-large-sorted.html
    Now let me make a guess why you observe the behaviour that it takes so long if your result set is empty:
    The plan avoiding the SORT ORDER BY is able to return the first rows of the result set very quickly, but could take quite a while until all rows are processed, since it requires potentially a lot of iterations of the loop until everything has been processed. Your front end probably by default only display the first n rows of the result set and therefore works fine with this execution plan.
    Now if the result set is empty, depending on your data, indexes and search criteria, Oracle has to work through all the data using the inefficient NESTED LOOP approach only to find out that no data has been found, and since your application attempts to fetch the first n records, but no records will be found, it has to wait until all data has been processed.
    You can try to reproduce this by deliberately fetching all records of a query that returns data and that uses the NESTED LOOP approach... It probably takes as long as in the case when no records are found.
    Note that you seem to use bind variables and 10g, therefore you might be interested that due to the "bind variable peeking" functionality you might potentially end up with "unstable" plans depending on the values "peeked" when the statement is parsed.
    For more information, see this comprehensive description of the issue:
    http://www.pythian.com/blogs/867/stabilize-oracle-10gs-bind-peeking-behaviour-by-cutting-histograms
    Note that this changes in 11g with the introduction of the "Adaptive Cursor Sharing".
    Regards,
    Randolf
    Oracle related stuff blog:
    http://oracle-randolf.blogspot.com/
    SQLTools++ for Oracle (Open source Oracle GUI for Windows):
    http://www.sqltools-plusplus.org:7676/
    http://sourceforge.net/projects/sqlt-pp/

  • Explain Plan in SQL Developer 1.5.1

    How do I run Explain Plan against a Stored Package using SQL Developer 1.5.1?
    I'm not familiar with this tool and need to examine a specific package.
    Thanks.

    AFAIK, you can only get an explain plan for SQL statements, not PL/SQL code...
    K.

  • [8i] Can someone help me on using explain plan, tkprof, etc.?

    I am trying to follow the instructions at When your query takes too long ...
    I am trying to figure out why a simple query takes so long.
    The query is:
    SELECT COUNT(*) AS tot_rows FROM my_table;It takes a good 5 minutes or so to run (best case), and the result is around 22 million (total rows).
    My generic username does not (evidently) allow access to PLAN_TABLE, so I had to log on as SYSTEM to run explain plan. In SQL*Plus, I typed in:
    explain plan for (SELECT COUNT(*) AS tot_rows FROM my_table);and the response was "Explained."
    Isn't this supposed to give me some sort of output, or am I missing something?
    Then, the next step in the post I linked is to use tkprof. I see that it says it will output a file to a path specified in a parameter. The only problem is, I don't have access to the db's server. I am working remotely, and do not have any way to remotely (or directly) access the db server. Is there any way to have the file output to my local machine, or am I just S.O.L.?

    SomeoneElse used "create table as" (CTAS), wich automatically gathers the stats. You can see the differende before and after stats clearly in this example.
    This is the script:
    drop table ttemp;
    create table ttemp (object_id number not null, owner varchar2(30), object_name varchar2(200));
    alter table ttemp add constraint ttemp_pk primary key (object_id);
    insert into ttemp
    select object_id, owner, object_name
    from dba_objects
    where object_id is not null;
    set autotrace on
    select count(*) from ttemp;
    exec dbms_stats.gather_table_stats('PROD','TTEMP');
    select count(*) from ttemp;And the result:
    Table dropped.
    Table created.
    Table altered.
    46888 rows created.
      COUNT(*)
         46888
    1 row selected.
    Execution Plan
               SELECT STATEMENT Optimizer Mode=CHOOSE
       1         SORT AGGREGATE
       2    1      TABLE ACCESS FULL PROD.TTEMP
    Statistics
              1  recursive calls
              1  db block gets
            252  consistent gets
              0  physical reads
            120  redo size
              0  PX remote messages sent
              0  PX remote messages recv'd
              0  buffer is pinned count
              0  workarea memory allocated
              4  workarea executions - optimal
              1  rows processed
    PL/SQL procedure successfully completed.
      COUNT(*)
         46888
    1 row selected.
    Execution Plan
               SELECT STATEMENT Optimizer Mode=CHOOSE (Cost=4 Card=1)
       1         SORT AGGREGATE (Card=1)
       2    1      INDEX FAST FULL SCAN PROD.TTEMP_PK (Cost=4 Card=46 K)
    Statistics
              1  recursive calls
              2  db block gets
            328  consistent gets
              0  physical reads
           8856  redo size
              0  PX remote messages sent
              0  PX remote messages recv'd
              0  buffer is pinned count
              0  workarea memory allocated
              4  workarea executions - optimal
              1  rows processed

  • Disadvantages in prepared statement

    hi
    i could not tell the answer for the following question in my interview can u pleae tell me the answer for this question
    one of the disadvantages with prepared statement in jdbc?

    I have no idea what WorkForFood is talking about.Sorry, perhaps an example will help clarify:
    Using a PreparedStatement using two replacement parameters:
    String sql = "SELECT COL1 FROM MYTABLE WHERE COL1 = ? AND COL2 = ?";
    ps.setSetring("WORK");
    ps.setString("FORFOOD");Contrasted against a Statement using literals:
    "SELECT COL1 FROM MYTABLE WHERE COL1 = 'WORK' AND COL2 = 'FORFOOD'";When you execute these two queries, they can generate different explain plans, for example the Statement may use an index while the PreparedStatement may attempt a full table scan. The optimizer is choosing a more efficient explain plan for the Statement because it has more information on which to make a decision (the literal values). A full table scan will be significantly slower then using an index to return the same results. In some databases, you can provide hints, but in some cases, the only way to get this query to use an index is to provide the actual values WORK and FORFOOD in the query itself. When using literals rather then replacement parameters it should be more efficient to use Statement then PreparedStatement (see jschell's list #1). So, in these cases, you should use a Statement rather then a PreparedStatement to get best performance from your query. And again, this issue comes up very infrequently but can be quite debilitating to an applications performance when it does occur.

  • SQLDeveloper can't generate an explain-plan when using "cube"

    If I want to create an explain-plan from the following statement, I get no explain-plan:
    SELECT 1
    FROM   dual
    GROUP BY CUBE( 2, 2, 2, 2, 2, 2, 2, 2, 2 )If I now want to create an explain-plan again, I get the following message (and still no explain-plan):
    http://i.imgur.com/mGO6Z.jpg
    I tried this a few times and of course with a fresh db-session where i didn't run any statements before.
    I get this with:
    SQLDeveloper Version 3.0.04 Build MAIN-04.34 (i.e. production)
    DB 9.2.0.1.0
    Oracle Instant Client 11.1.0.6.0
    In Toad this works btw.
    (Of course it makes no sense to run it on this statement, we encountered this problem with a really big SQL-statement where "cube" was used in an inline-view. SQLDeveloper then wasn't able to generate an explain-plan for the whole-statement)
    Regards
    Markus

    that is correct.  I wanted to keep the login page redirect inside my class method so that I could do the check every time someone came to pages that require authentication. I wanted it in the LoadState method so I can do a check there, redirect
    them to login page or just get a cookie and then pass that cookie to page to build the UI for the page
    I can do what you are suggesting and have actually tried it but then I have to track which page to take the user to after they log in...
    I have multiple clicks in the appbar  and pages from where the user can come to these authentication-bound pages..
    Suggestions?
    Also, what am I doing wrong in my class method that it doesn't navigate to the login page in the LoadState method?
    Thanks 
    mujno

  • Explain Plan from TKPROF trace file.

    Hello,
    My procedure is taking time for that i have trace on in procedure fo find explain plan of particular query.
    Using below statement Trace is on.
       EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE = TRUE';
       EXECUTE IMMEDIATE 'ALTER SESSION SET TIMED_STATISTICS = TRUE';Now for getting expalin plan from TKPROF i have used below statement but for some query i have found explain paln and some case i cant found explain plan.
    tkprof mf_ora_23773.trc mf_ora_23773.txt explain =abc/abc
    can u please help me to analyze where i m wrong?
    Thanks.

    First of all, you should best avoid using the explain= clause on the tkprof command line.
    This will run explain plan on the statement in the trace file, and that explain plan can even be wrong, as there is no information on datatypes in the trace file.
    The real explain plan data is flushed to the trace file, when the program issues commit or rollback. Oracle always issues an implicit commit when the program disconnects, so when you run the program to completion you should have explain plan output in your trace files.
    You won't get explain plan output if you don't have access to the objects in the SQL statement. Also recursive SQL won't produce explain plan result.
    One would need to see part of your trace file to verify your assertion the explain clause doesn't always work.
    Sybrand Bakker
    Senior Oracle DBA

Maybe you are looking for