Different query plans for same query on same DB
Hi,
HP-Ux
Oracle Database 10.2.0.4
We are experiencing a strange issue. One of our night batch process is taking invariably more time to execute. The process does not consume time at 1 particular query. Everyday we find a new query taking more time than previous execution.
Now, when we see the explain plan while the query is executing, we see NESTED LOOP SEMI (with improper index being used). At the same time if we take the query and see the explain plan seperately, we get HASH JOIN SEMI (with proper index being used). Also, if we execute this query with the values as in procedure, it finishes within mili seconds (as it should).
The tables and indexes are analyzed everyday before the process starts.
Can anybody explain, why the same query shows two different plans at the same time ?
Thanks a lot in advance :)
Aalap Sharma wrote:
HP-Ux
Oracle Database 10.2.0.4
We are experiencing a strange issue. One of our night batch process is taking invariably more time to execute. The process does not consume time at 1 particular query. Everyday we find a new query taking more time than previous execution.
Now, when we see the explain plan while the query is executing, we see NESTED LOOP SEMI (with improper index being used). At the same time if we take the query and see the explain plan seperately, we get HASH JOIN SEMI (with proper index being used). Also, if we execute this query with the values as in procedure, it finishes within mili seconds (as it should).
The tables and indexes are analyzed everyday before the process starts.
Can anybody explain, why the same query shows two different plans at the same time ?As already mentioned, you might hit typical issues in 10.2: The column workload based SIZE AUTO statistics gathering feature and/or bind variable peeking.
How do you analyze the tables and indexes before the process starts? Can you share the exact call with parameters?
Some ideas:
1. If your process is "new", then the column workload monitoring of the database might recognize the column usage pattern and generate histograms on some of your columns. It might take a while until the workload has been established so that all columns got histograms according to the workload (It needs a certain number of usages/executions before the workload is registered as relevant). Until then you might get different execution plans each time the statistics are refreshed due to new histograms being added.
2. If the default 10g statistics gathering job is active, it might gather different statistics during the night than your individual job that runs prior to the processing. This could be one possible explanation why you get different plans on the next day.
3. "Bind Variable Peeking" is possibly another issue you might run into. How do you test the query so that you get a different, well performing plan? Does your original statement use bind variables? Do you use literals to reproduce? Note that using EXPLAIN PLAN on statements involving bind variables can lie, since it doesn't perform bind variable peeking by default.
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/
Similar Messages
-
How to skip existing execution plan for a query
Hi,
I want to skip existng execution plan for a query which I am executing often. I dont want it to use the same execution plan everytime. Please let me know if any method is there skip the existing execution plan.
Thanks in advance.......
Edited by: 900105 on Dec 1, 2011 4:52 AMChange the query so it is syntactically different, but has the same semantics (meaning). That way CBO will reparse it and you might get a new execution plan.
One simple way to do that is to add a dummy predicate ( 45=45) to the where clause. The predicate must be changed every time the query is executed ( 46=46 , 47=47 ,… ).
Iordan Iotzov
http://iiotzov.wordpress.com/ -
How to capture the execution plan for a query
HI All,
Can anyone please help me in finding out the command to capture the execution plan for a query.
Execution plan for select * from EMP where <Condtions>
it is getting executed successfully but i need to get the proper execution plan for the same.
Thanks971830 wrote:
i want to know where execution plan gets generated??
in PMON of server process or in shared pool??
i know that optimixer create execution plan..It is stored in Library Cache (present inside Shared Pool ).
select * from v$sql_plan;An absolute beautiful white paper :
Refer this -- www.sagelogix.com/sagelogix/SearchResults/SAGE015052
Also -- http://www.toadworld.com/KNOWLEDGE/KnowledgeXpertforOracle/tabid/648/TopicID/XPVSP/Default.aspx
HTH
Ranit B. -
We are interested to know how/where to check query runtimes for any Query in SAP BW?
We are interested to know how/where to check query runtimes for any Query in SAP BW?
Is there any table or program to get the query run time details per query for a particular day.Hello Sravan,
Bex statics tables would be 'RSDDSTATHEADER','RSDDSTATINFO' & 'RSDDSTATEVDATA'. all these can found in one view 'RSDDSTAT_OLAP'.
above can give historical statistic.
For current Query statics : T-code RSRT, and select debug mode select display statistics and then execute.
Once you get the output press F3(one step back), there you can see statics of the query for that particular execution.
Thanks,
Mallikarjuna -
Different execution plan for same query but for different condition value
Hi All,
I'm facing a strange situation where same query for different condition not working.
1--
Select top 10 * from revenuefact(nolock)
where feecode ='OW4'
2--
Select top 10 * from revenuefact(nolock)
where feecode ='BTE'
1st query is returning result easily but 2nd query is taking too long. Column
feecode has already Non-clustered index and Clustered index is also available for another col RevenueSID.
I was surprised when checked the query execution plan for both the above queries which is quite different (as per attached below). Can anyone suggest me the reason behind it.
And solution for the same. One more thing that data for feecode BTE is inserting through different source instead of others feecode and table contains more than 300 million rows.When I speak with people inside Microsoft who work with the optimizer, the refuse to accept the work "bug" when a query produces the correct result, but with a suboptimal plan. They prefer to use the word "limitation".
The limitation here is that when the optimizer compares two plans, it only looks at the estimated cost. As far as I know, it does not perform any analysis from the perspective "what if the statistics are wrong"? They do provide the hint OPTIMIZE
FOR UNKNOWN, but that does not work then there is a constant as in this case.
The optimizer will surely distinguish between TOP 10 and TOP 10000000. With the latter, you have all reason to expect a Clustered Index Scan no matter which value you search for - unless you pick a value for which the histogram indicates that there are no
rows.
Interesting enough, I was able to reproduce the situation in my Northgale database, which is an inflated version of Northwind, and where statistics should be accurate.
SELECT TOP 10 * FROM Orders WHERE EmployeeID = 8
results in a CI scan, and so does also EmployeeID = 7, and even 5. There are only 2292 rows out of a total of 344305 rows. If I try EmployeeID 808 for which there are 1797, the optimizer goes for the index seek.
Erland Sommarskog, SQL Server MVP, [email protected] -
Why two different explain plan for same objects?
Believe or not there are two different databases, one for processing and one for reporting, plan is show different for same query. Table structure and indexes are same. It's 11G
Thanks
Good explain plan .. works fine..
Plan
SELECT STATEMENT ALL_ROWSCost: 12,775 Bytes: 184 Cardinality: 1
27 SORT UNIQUE Cost: 12,775 Bytes: 184 Cardinality: 1
26 NESTED LOOPS
24 NESTED LOOPS Cost: 12,774 Bytes: 184 Cardinality: 1
22 HASH JOIN Cost: 12,772 Bytes: 178 Cardinality: 1
20 NESTED LOOPS SEMI Cost: 30 Bytes: 166 Cardinality: 1
17 NESTED LOOPS Cost: 19 Bytes: 140 Cardinality: 1
14 NESTED LOOPS OUTER Cost: 16 Bytes: 84 Cardinality: 1
11 VIEW DSSADM. Cost: 14 Bytes: 37 Cardinality: 1
10 NESTED LOOPS
8 NESTED LOOPS Cost: 14 Bytes: 103 Cardinality: 1
6 NESTED LOOPS Cost: 13 Bytes: 87 Cardinality: 1
3 INLIST ITERATOR
2 TABLE ACCESS BY INDEX ROWID TABLE DSSODS.DRV_PS_JOB_FAMILY_TBL Cost: 10 Bytes: 51 Cardinality: 1
1 INDEX RANGE SCAN INDEX DSSODS.DRV_PS_JOB_FAMILY_TBL_CL_SETID Cost: 9 Cardinality: 1
5 TABLE ACCESS BY INDEX ROWID TABLE DSSADM.DIM_JOBCODE Cost: 3 Bytes: 36 Cardinality: 1
4 INDEX RANGE SCAN INDEX DSSADM.STAN_JB_FN_IDX Cost: 2 Cardinality: 1
7 INDEX UNIQUE SCAN INDEX (UNIQUE) DSSODS.DRV_PS_JOBCODE_TBL_SEQ_KEY_RPT Cost: 0 Cardinality: 1
9 TABLE ACCESS BY INDEX ROWID TABLE DSSODS.DRV_PS_JOBCODE_TBL_RPT Cost: 1 Bytes: 16 Cardinality: 1
13 TABLE ACCESS BY INDEX ROWID TABLE DSSODS.DRV_PSXLATITEM_RPT Cost: 2 Bytes: 47 Cardinality: 1
12 INDEX RANGE SCAN INDEX DSSODS.PK_DRV_RIXLATITEM_RPT Cost: 1 Cardinality: 1
16 TABLE ACCESS BY INDEX ROWID TABLE DSSADM.DIM_JOBCODE Cost: 3 Bytes: 56 Cardinality: 1
15 INDEX RANGE SCAN INDEX DSSADM.DIM_JOBCODE_EXPDT1 Cost: 2 Cardinality: 1
19 TABLE ACCESS BY INDEX ROWID TABLE DSSODS.DRV_PS_JOB_RPT Cost: 11 Bytes: 438,906 Cardinality: 16,881
18 INDEX RANGE SCAN INDEX DSSODS.DRV_PS_JOB_JOBCODE_RPT Cost: 2 Cardinality: 8
21 INDEX FAST FULL SCAN INDEX (UNIQUE) DSSADM.Z_PK_JOBCODE_PROMPT_TBL Cost: 12,699 Bytes: 66,790,236 Cardinality: 5,565,853
23 INDEX RANGE SCAN INDEX DSSADM.DIM_PERSON_EMPL_RCD_SEQ_KEY Cost: 1 Cardinality: 1
25 TABLE ACCESS BY INDEX ROWID TABLE DSSADM.DIM_PERSON_EMPL_RCD Cost: 2 Bytes: 6 Cardinality: 1 This bad plan ... show merge join cartesian and full table ..
Plan
SELECT STATEMENT ALL_ROWSCost: 3,585 Bytes: 237 Cardinality: 1
26 SORT UNIQUE Cost: 3,585 Bytes: 237 Cardinality: 1
25 NESTED LOOPS SEMI Cost: 3,584 Bytes: 237 Cardinality: 1
22 NESTED LOOPS Cost: 3,573 Bytes: 211 Cardinality: 1
20 MERGE JOIN CARTESIAN Cost: 2,864 Bytes: 70,446 Cardinality: 354
17 NESTED LOOPS
15 NESTED LOOPS Cost: 51 Bytes: 191 Cardinality: 1
13 NESTED LOOPS OUTER Cost: 50 Bytes: 180 Cardinality: 1
10 HASH JOIN Cost: 48 Bytes: 133 Cardinality: 1
6 NESTED LOOPS
4 NESTED LOOPS Cost: 38 Bytes: 656 Cardinality: 8
2 TABLE ACCESS BY INDEX ROWID TABLE REPORT2.DIM_JOBCODE Cost: 14 Bytes: 448 Cardinality: 8
1 INDEX RANGE SCAN INDEX REPORT2.STAN_PROM_JB_IDX Cost: 6 Cardinality: 95
3 INDEX RANGE SCAN INDEX REPORT2.SETID_JC_IDX Cost: 2 Cardinality: 1
5 TABLE ACCESS BY INDEX ROWID TABLE REPORT2.DIM_JOBCODE Cost: 3 Bytes: 26 Cardinality: 1
9 INLIST ITERATOR
8 TABLE ACCESS BY INDEX ROWID TABLE REPORT2.DRV_PS_JOB_FAMILY_TBL Cost: 10 Bytes: 51 Cardinality: 1
7 INDEX RANGE SCAN INDEX REPORT2.DRV_PS_JOB_FAMILY_TBL_CL_SETID Cost: 9 Cardinality: 1
12 TABLE ACCESS BY INDEX ROWID TABLE REPORT2.DRV_PSXLATITEM_RPT Cost: 2 Bytes: 47 Cardinality: 1
11 INDEX RANGE SCAN INDEX REPORT2.PK_DRV_RIXLATITEM_RPT Cost: 1 Cardinality: 1
14 INDEX UNIQUE SCAN INDEX (UNIQUE) REPORT2.DRV_PS_JOBCODE_TBL_SEQ_KEY_RPT Cost: 0 Cardinality: 1
16 TABLE ACCESS BY INDEX ROWID TABLE REPORT2.DRV_PS_JOBCODE_TBL_RPT Cost: 1 Bytes: 11 Cardinality: 1
19 BUFFER SORT Cost: 2,863 Bytes: 4,295,552 Cardinality: 536,944
18 TABLE ACCESS FULL TABLE REPORT2.DIM_PERSON_EMPL_RCD Cost: 2,813 Bytes: 4,295,552 Cardinality: 536,944
21 INDEX RANGE SCAN INDEX (UNIQUE) REPORT2.Z_PK_JOBCODE_PROMPT_TBL Cost: 2 Bytes: 12 Cardinality: 1
24 TABLE ACCESS BY INDEX ROWID TABLE REPORT2.DRV_PS_JOB_RPT Cost: 11 Bytes: 1,349,920 Cardinality: 51,920
23 INDEX RANGE SCAN INDEX REPORT2.DRV_PS_JOB_JOBCODE_RPT Cost: 2 Cardinality: 8user550024 wrote:
I am really surprise that the stat for good sql are little old. I just computed the states of bad sql so they are uptodate..
There is something terribly wrong..Not necessarily. Just using the default stats collection I've seen a few cases of things suddenly going wrong. As the data increases, it gets closer to an edge case where the inadequacy of the statistics convinces the optimizer to do a wrong plan. To fix, I could just go into dbconsole, set the stats back to a time when they worked, and locked them. In most cases it's definitely better to figure out what is really going on, though, to give the optimizer better information to work with. Aside from the value of learning how to do it, for some cases it's not so simple. Also, many think the default settings of the database statistic collection may be wrong in general (in 10.2.x, at least). So much depends on your application and data that you can't make too many generalizations. You have to look at the evidence and figure it out. There is still a steep learning curve for the tools to look at the evidence. People are here to help with that.
Most of the time it works better than a dumb rule based optimizer, but at the cost of a few situations where people are smarter than computers. It's taken a lot of years to get to this point. -
Different execution plans for the same sql
Hi,
Im testing our new 10gR2 database on Linux and I can't understand why the same query use different plan.
Here are the details.
Table name: invoice_detail
Records: About 10,670,900
Columns:
No
seq (the primary key is No+Seq). Each invoices contains +/- 10 invoice_details.
category ( <- 10 different values )
State ( <- 3 different values )
Basically, I have an index on the primary key and another index on Category + State.
My request:
select *
from invoice_detail
where no=123456 <- Best index to use
and state <> 'CANCEL'
and category = 'INVOICE'
If i run this query from Toad or sql+, that's fine.
The same query (i'm watching it from EM) executed via Forms use the category+state index.
When I first import the database, the last thing I do is to run DBMS_STATS.GATHER_DATABASE_STATS.
At this point, Forms use the right index.
The day after (after the database has been analyzed with the predefined job via EM) Forms use the wrong index.
I re-analyzed everything with exec DBMS_STATS.GATHER_DATABASE_STATS but the problem is still there.
Thanks in advanceI'm already using bind variables.
I changed the "Estimated Percentage" to 100% in "Gather Optimizer Statistics Default Options" and now it seems to use the correct index. I'm stressed because I dont understand why it chooses different plan for the same sql.
Actually, my users test the migration 1 day after I load all the data (drop schema-create schema-load data-analyze database) and at this point everythings go fine. After the second analyze of the database, the DB choose the wrong indexes.
I really cannot migrate until I understand why it happens.
Any ideas?
TIA -
One query - one database - different execution plan for different users.
Hi everyone.
I've encountered one of the strangest things I've ever seen with Oracle. I'm hoping that someone else here has seen something like this before and solved it! On an 11g database I have a query that runs differently depending on which user runs it. If the owner of the tables or someone with the DBA role runs the query I get a perfect execution plan. If someone else runs it, I get a really bad execution plan - though the query still executes. So it almost seems like depending on who is running the query, the optimizer might not have access to the same statistics?? I'm really grasping at straws here - any help would be greatfully accepted!!!
Here is the query and the two plans for it...
On TASD as a General User (Bad execution plan) - CA17062 is USER
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.3.0
Connected as ca17062
SQL> explain plan for
select w.worker_id, w.worker_name
from worker_v w,
worker_cost_centre_v c
where w.worker_id = c.worker_id
and c.effective_date <= trunc(sysdate)
and c.expiration_date >= trunc(sysdate)
and c.cost_centre = '100033'
and pkg_taw_security.user_worker_access('CA17062',
'TIMEKEEPER',
w.worker_id,
trunc(sysdate)) = 1
order by w.worker_name;
Explained
Executed in 0.234 seconds
PLAN_TABLE_OUTPUT
Plan hash value: 1726112176
| Id | Pid | Ord | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | | 8 | SELECT STATEMENT | | 18 | 1800 | 606 (1)| 00:00:01 |
| 1 | 0 | 7 | SORT ORDER BY | | 18 | 1800 | 606 (1)| 00:00:01 |
|* 2 | 1 | 6 | HASH JOIN | | 18 | 1800 | 605 (1)| 00:00:01 |
| 3 | 2 | 3 | VIEW | WORKER_COST_CENTRE_V | 18 | 558 | 19 (0)| 00:00:01 |
|* 4 | 3 | 2 | TABLE ACCESS BY INDEX ROWID| WORKER_COST_CENTRE_TBL | 18 | 522 | 19 (0)| 00:00:01 |
|* 5 | 4 | 1 | INDEX RANGE SCAN | WORKER_CC_CC_IDX | 29 | | 3 (0)| 00:00:01 |
|* 6 | 2 | 5 | VIEW | WORKER_V | 161K| 10M| 584 (1)| 00:00:01 |
| 7 | 6 | 4 | TABLE ACCESS FULL | WORKER_TBL | 161K| 3466K| 584 (1)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("W"."WORKER_ID"="C"."WORKER_ID")
4 - filter("X"."EXPIRATION_DATE">=TRUNC(SYSDATE@!))
PLAN_TABLE_OUTPUT
5 - access("X"."COST_CENTRE"='100033' AND "X"."EFFECTIVE_DATE"<=TRUNC(SYSDATE@!))
6 - filter("PKG_TAW_SECURITY"."USER_WORKER_ACCESS"('CA17062','TIMEKEEPER',"W"."WORKER_ID",TRUN
C(SYSDATE@!))=1)
About
- XPlan v1.2 by Adrian Billington (http://www.oracle-developer.net)
23 rows selected
Executed in 0.577 seconds
WORKER_ID WORKER_NAME
123703 FADDEN, CLAYTON
11131 HAHN, BRAD
33811 HALL, MAUREEN
53934 JANES, CATHERINE
Executed in 35.241 seconds
On TASD as the owner of the tables or as someone with the DBA role (Good Execution) - TAS is USER:
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.3.0
Connected as tas
SQL> explain plan for
select w.worker_id, w.worker_name
from worker_v w,
worker_cost_centre_v c
where w.worker_id = c.worker_id
and c.effective_date <= trunc(sysdate)
and c.expiration_date >= trunc(sysdate)
and c.cost_centre = '100033'
and pkg_taw_security.user_worker_access('CA17062',
'TIMEKEEPER',
w.worker_id,
trunc(sysdate)) = 1
order by w.worker_name;
Explained
Executed in 0.203 seconds
PLAN_TABLE_OUTPUT
Plan hash value: 3435904055
| Id | Pid | Ord | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | | 8 | SELECT STATEMENT | | 18 | 918 | 38 (3)| 00:00:01 |
| 1 | 0 | 7 | SORT ORDER BY | | 18 | 918 | 38 (3)| 00:00:01 |
| 2 | 1 | 6 | NESTED LOOPS | | | | | |
| 3 | 2 | 4 | NESTED LOOPS | | 18 | 918 | 37 (0)| 00:00:01 |
|* 4 | 3 | 2 | TABLE ACCESS BY INDEX ROWID| WORKER_COST_CENTRE_TBL | 18 | 522 | 19 (0)| 00:00:01 |
|* 5 | 4 | 1 | INDEX RANGE SCAN | WORKER_CC_CC_IDX | 29 | | 3 (0)| 00:00:01 |
|* 6 | 3 | 3 | INDEX UNIQUE SCAN | WORKER_PK | 1 | | 0 (0)| 00:00:01 |
| 7 | 2 | 5 | TABLE ACCESS BY INDEX ROWID | WORKER_TBL | 1 | 22 | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
4 - filter("X"."EXPIRATION_DATE">=TRUNC(SYSDATE@!))
5 - access("X"."COST_CENTRE"='100033' AND "X"."EFFECTIVE_DATE"<=TRUNC(SYSDATE@!))
PLAN_TABLE_OUTPUT
6 - access("X"."WORKER_ID"="X"."WORKER_ID")
filter("PKG_TAW_SECURITY"."USER_WORKER_ACCESS"('CA17062','TIMEKEEPER',"X"."WORKER_ID",TRUN
C(SYSDATE@!))=1)
About
- XPlan v1.2 by Adrian Billington (http://www.oracle-developer.net)
23 rows selected
Executed in 0.624 seconds
WORKER_ID WORKER_NAME
123703 FADDEN, CLAYTON
11131 HAHN, BRAD
33811 HALL, MAUREEN
53934 JANES, CATHERINE
Executed in 1.307 seconds
THANKS!!!
Cory AstonI reran the whole thing - with full declared view names and display_cursor. Here are the results...
On TASD as CA17062 (BAD EXECUTION PLAN)
SQL> set linesize 160
SQL> set serveroutput off
SQL>
SQL> select /*+ gather_plan_statistics */
2 w.worker_id, w.worker_name
3 from tas.worker_v w,
4 tas.worker_cost_centre_v c
5 where w.worker_id = c.worker_id
6 and c.effective_date <= trunc(sysdate)
7 and c.expiration_date >= trunc(sysdate)
8 and c.cost_centre = '100033'
9 and tas_user.pkg_taw_security.user_worker_access('CA17062',
10 'TIMEKEEPER',
11 w.worker_id,
12 trunc(sysdate)) = 1
13 order by w.worker_name;
WORKER_ID WORKER_NAME
123703 FADDEN, CLAYTON
11131 HAHN, BRAD
33811 HALL, MAUREEN
53934 JANES, CATHERINE
SQL>
SQL> select * from table(dbms_xplan.display_cursor(null, null, 'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
SQL_ID gs5vtgany8vbv, child number 3
select /*+ gather_plan_statistics */ w.worker_id, w.worker_name
from tas.worker_v w, tas.worker_cost_centre_v
c where w.worker_id = c.worker_id and c.effective_date <=
trunc(sysdate) and c.expiration_date >= trunc(sysdate) and
c.cost_centre = '100033' and tas_user.pkg_taw_security.user_worker_ac
cess('CA17062',
'TIMEKEEPER', w.worker_id,
trunc(sysdate)) = 1 order by
w.worker_name
Plan hash value: 1726112176
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
| 0 | SELECT STATEMENT | | 1 | | 4 |00:00:18.52 | 947K| | | |
| 1 | SORT ORDER BY | | 1 | 4 | 4 |00:00:18.52 | 947K| 2048 | 2048 | 2048 (0)|
|* 2 | HASH JOIN | | 1 | 4 | 4 |00:00:15.84 | 947K| 1348K| 1348K| 791K (0)|
| 3 | VIEW | WORKER_COST_CENTRE_V | 1 | 4 | 4 |00:00:00.01 | 18 | | | |
|* 4 | TABLE ACCESS BY INDEX ROWID| WORKER_COST_CENTRE_TBL | 1 | 4 | 4 |00:00:00.01 | 18 | | | |
|* 5 | INDEX RANGE SCAN | WORKER_CC_CC_IDX | 1 | 29 | 21 |00:00:00.01 | 3 | | | |
|* 6 | VIEW | WORKER_V | 1 | 161K| 4 |00:00:15.84 | 946K| | | |
| 7 | TABLE ACCESS FULL | WORKER_TBL | 1 | 161K| 160K|00:00:00.09 | 2135 | | | |
Predicate Information (identified by operation id):
2 - access("W"."WORKER_ID"="C"."WORKER_ID")
4 - filter("X"."EXPIRATION_DATE">=TRUNC(SYSDATE@!))
5 - access("X"."COST_CENTRE"='100033' AND "X"."EFFECTIVE_DATE"<=TRUNC(SYSDATE@!))
6 - filter("PKG_TAW_SECURITY"."USER_WORKER_ACCESS"('CA17062','TIMEKEEPER',"W"."WORKER_ID",TRUNC(SYSDATE@!))=1)
Note
- cardinality feedback used for this statement
39 rows selected.
SQL>
On TASD as TAS: (GOOD EXECUTION PLAN)
SQL> set serveroutput off
SQL>
SQL> select /*+ gather_plan_statistics */
2 w.worker_id, w.worker_name
3 from tas.worker_v w,
4 tas.worker_cost_centre_v c
5 where w.worker_id = c.worker_id
6 and c.effective_date <= trunc(sysdate)
7 and c.expiration_date >= trunc(sysdate)
8 and c.cost_centre = '100033'
9 and tas_user.pkg_taw_security.user_worker_access('CA17062',
10 'TIMEKEEPER',
11 w.worker_id,
12 trunc(sysdate)) = 1
13 order by w.worker_name;
WORKER_ID WORKER_NAME
123703 FADDEN, CLAYTON
11131 HAHN, BRAD
33811 HALL, MAUREEN
53934 JANES, CATHERINE
SQL>
SQL> select * from table(dbms_xplan.display_cursor(null, null, 'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
SQL_ID gs5vtgany8vbv, child number 1
select /*+ gather_plan_statistics */ w.worker_id, w.worker_name
from tas.worker_v w, tas.worker_cost_centre_v
c where w.worker_id = c.worker_id and c.effective_date <=
trunc(sysdate) and c.expiration_date >= trunc(sysdate) and
c.cost_centre = '100033' and tas_user.pkg_taw_security.user_worker_ac
cess('CA17062',
'TIMEKEEPER', w.worker_id,
trunc(sysdate)) = 1 order by
w.worker_name
Plan hash value: 3435904055
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
| 0 | SELECT STATEMENT | | 1 | | 4 |00:00:00.01 | 185 | | | |
| 1 | SORT ORDER BY | | 1 | 4 | 4 |00:00:00.01 | 185 | 2048 | 2048 | 2048 (0)|
| 2 | NESTED LOOPS | | 1 | | 4 |00:00:00.01 | 185 | | | |
| 3 | NESTED LOOPS | | 1 | 4 | 4 |00:00:00.01 | 181 | | | |
|* 4 | TABLE ACCESS BY INDEX ROWID| WORKER_COST_CENTRE_TBL | 1 | 4 | 4 |00:00:00.01 | 18 | | | |
|* 5 | INDEX RANGE SCAN | WORKER_CC_CC_IDX | 1 | 29 | 21 |00:00:00.01 | 3 | | | |
|* 6 | INDEX UNIQUE SCAN | WORKER_PK | 4 | 1 | 4 |00:00:00.01 | 163 | | | |
| 7 | TABLE ACCESS BY INDEX ROWID | WORKER_TBL | 4 | 1 | 4 |00:00:00.01 | 4 | | | |
Predicate Information (identified by operation id):
4 - filter("X"."EXPIRATION_DATE">=TRUNC(SYSDATE@!))
5 - access("X"."COST_CENTRE"='100033' AND "X"."EFFECTIVE_DATE"<=TRUNC(SYSDATE@!))
6 - access("X"."WORKER_ID"="X"."WORKER_ID")
filter("PKG_TAW_SECURITY"."USER_WORKER_ACCESS"('CA17062','TIMEKEEPER',"X"."WORKER_ID",TRUNC(SYSDATE@!))=1)
Note
- cardinality feedback used for this statement
39 rows selected.
SQL> -
Different 'execution plans' for same sql in 10R2
DB=10.2.0.5
OS=RHEL 3
Im not sure of this, but seeing different plans for same SQL.
select sql_text from v$sqlarea where sql_id='92mb4z83fg4st'; <---TOP SQL from AWR
SELECT /*+ OPAQUE_TRANSFORM */ "ENDUSERID","LASTLOGINATTEMPTTIMESTAMP","LOGINSOURCECD","LOGINSUCCESSFLG",
"ENDUSERLOGINATTEMPTHISTORYID","VERSION_NUM","CREATEDATE"
FROM "BOMB"."ENDUSERLOGINATTEMPTHISTORY" "ENDUSERLOGINATTEMPTHISTORY";
SQL> set autotrace traceonly
SQL> SELECT /*+ OPAQUE_TRANSFORM */ "ENDUSERID","LASTLOGINATTEMPTTIMESTAMP","LOGINSOURCECD","LOGINSUCCESSFLG",
"ENDUSERLOGINATTEMPTHISTORYID","VERSION_NUM","CREATEDATE"
FROM "BOMB"."ENDUSERLOGINATTEMPTHISTORY" "ENDUSERLOGINATTEMPTHISTORY"; 2 3
1822203 rows selected.
Execution Plan
Plan hash value: 568996432
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1803K| 75M| 2919 (2)| 00:00:36 |
| 1 | TABLE ACCESS FULL| ENDUSERLOGINATTEMPTHISTORY | 1803K| 75M| 2919 (2)| 00:00:36 |
Statistics
0 recursive calls
0 db block gets
133793 consistent gets
0 physical reads
0 redo size
76637183 bytes sent via SQL*Net to client
1336772 bytes received via SQL*Net from client
121482 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1822203 rows processed
===================================== another plan ===============
SQL> select * from TABLE(dbms_xplan.display_awr('92mb4z83fg4st'));
15 rows selected.
Execution Plan
Plan hash value: 3015018810
| Id | Operation | Name |
| 0 | SELECT STATEMENT | |
| 1 | COLLECTION ITERATOR PICKLER FETCH| DISPLAY_AWR |
Note
- rule based optimizer used (consider using cbo)
Statistics
24 recursive calls
24 db block gets
49 consistent gets
0 physical reads
0 redo size
1529 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
15 rows processed
=========second one shows only 15 rows...
Which one is correct ?Understood, second plan is for self 'dbms_xplan'.
Anyhow I opened a new session where I did NOT on 'auto-trace'. but plan is somewhat than the original.
SQL> /
PLAN_TABLE_OUTPUT
SQL_ID 92mb4z83fg4st
SELECT /*+ OPAQUE_TRANSFORM */ "ENDUSERID","LASTLOGINATTEMPTTIMESTAMP","LOGINSOURCECD","
LOGINSUCCESSFLG","ENDUSERLOGINATTEMPTHISTORYID","VERSION_NUM","CREATEDATE" FROM
"BOMB"."ENDUSERLOGINATTEMPTHISTORY" "ENDUSERLOGINATTEMPTHISTORY"
Plan hash value: 568996432
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
PLAN_TABLE_OUTPUT
| 0 | SELECT STATEMENT | | | | 2919 (100)| |
| 1 | TABLE ACCESS FULL| ENDUSERLOGINATTEMPTHISTORY | 1803K| 75M| 2919 (2)| 00:00:36 |
15 rows selected.
I am just wondering, which plan is the accurate and which I need to believe ? -
'dbms_xplan.display_awr' is showing two plan for single query
Hi,
I am trying to fetch sql plan from awr, but it's showing two different plans for a single query:
PLAN_TABLE_OUTPUT
SQL_ID 2pxv33cr271sb
SELECT P_DEP_BNK_CODE,P_DEP_BRN_CODE,P_DEP_DATE,
P_DEP_DAY_SL,P_DEP_INST_SL,P_INST_AMT
FROM P WHERE
P_DEP_BNK_CODE = :1 AND
P_DEP_BRN_CODE = :2 AND
P_DEP_DATE = :3 AND
P_DEP_LCC_UCC = :4 AND
P_DEP_DAY_SL = :5 AND
(P_REALISED_ON IS NULL AND
P_RTN_DATE IS NULL)
Plan hash value: 3064382432
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
| 0 | SELECT STATEMENT | | | | 5 (100)| | | |
| 1 | TABLE ACCESS BY GLOBAL INDEX ROWID| P | 1 | 40 | 5 (0)| 00:00:01 | ROWID | ROWID |
| 2 | INDEX RANGE SCAN | P_PK | 1 | | 4 (0)| 00:00:01 | | |
Note
- dynamic sampling used for this statement (level=5)
SQL_ID 2pxv33cr271sb
SELECT P_DEP_BNK_CODE,P_DEP_BRN_CODE,P_DEP_DATE,
P_DEP_DAY_SL,P_DEP_INST_SL,P_INST_AMT
FROM P WHERE
P_DEP_BNK_CODE = :1 AND
P_DEP_BRN_CODE = :2 AND
P_DEP_DATE = :3 AND
P_DEP_LCC_UCC = :4 AND
P_DEP_DAY_SL = :5 AND
(P_REALISED_ON IS NULL AND
P_RTN_DATE IS NULL)
Plan hash value: 3447007225
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
| 0 | SELECT STATEMENT | | | | 7 (100)| | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | | |
| 2 | PX SEND QC (RANDOM)| :TQ10000 | 1 | 38 | 7 (43)| 00:00:01 | | | Q1,00 | P->S | QC (RAND) |
| 3 | PX BLOCK ITERATOR | | 1 | 38 | 7 (43)| 00:00:01 | KEY | KEY | Q1,00 | PCWC | |
| 4 | TABLE ACCESS FULL| P | 1 | 38 | 7 (43)| 00:00:01 | KEY | KEY | Q1,00 | PCWP | |
------------------------------------------------------------------------------------------------------------------------------The database version is 11.2.0.1 and the underlying table is partitioned. Why this is showing two plans? Although the plan doesn't look expensive but this is causing maximum gets and enq: row lock contention
Regards,
RegardsSQL> set autot on
SQL> SELECT
2 SUM(NVL(P_INST_AMT, 0))
3 FROM
4 AXISCMS.P
5 WHERE
6 P_DEP_BNK_CODE = '211'
7 AND
8 P_DEP_BRN_CODE = '005'
9 AND
10 P_DEP_DATE = to_date('11-NOV-2010')
11 AND
12 P_DEP_LCC_UCC = 'L'
13 AND
P_DEP_DAY_SL = 15001
14 15 AND
16 (P_REALISED_ON IS NOT NULL OR P_RTN_DATE IS NOT NULL );
SUM(NVL(P_INST_AMT,0))
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost | Pstart| Pstop |
| 0 | SELECT STATEMENT | | 1 | 38 | 8 | | |
| 1 | SORT AGGREGATE | | 1 | 38 | | | |
| 2 | TABLE ACCESS BY GLOBAL INDEX ROWID| P | 1 | 38 | 8 | 72 | 72 |
| 3 | INDEX RANGE SCAN | P_PK | 1 | | 4 | | |
Note
- 'PLAN_TABLE' is old version
Statistics
5 recursive calls
0 db block gets
370 consistent gets
31 physical reads
0 redo size
543 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processedThe above query seems to be having cheapest cost but causing a lot of slowness in the database.
Column Description:
COLUMN_NAME DATA_TYPE NUM_DISTINCT NUM_NULLS DENSITY HISTOGRAM
P_AC_NAME VARCHAR2 244672 49251591 4.0871E-06 NONE
P_AC_NO VARCHAR2 413792 48713721 2.4167E-06 NONE
P_ARNGMNT_CREDIT_DATE DATE 1708 39366743 .001724138 HEIGHT BALANCED
P_AUTOLIQ_ACT_DATE DATE 358 50356077 .003003003 HEIGHT BALANCED
P_AUTOLIQ_DUE_DATE DATE 337 50427426 .002967359 NONE
P_AUTOLIQ_FLAG CHAR 1 44746714 1 NONE
P_CLG_DNLD_FLAG NUMBER 1 50481119 .035714286 FREQUENCY
P_CORR_BANK_REAL_DATE DATE 0 50481133 0 NONE
P_DEP_BNK_CODE VARCHAR2 16 0 9.9454E-09 FREQUENCY
P_DEP_BRN_CODE VARCHAR2 671 0 .002531646 HEIGHT BALANCEDIndex Details
INDEX_NAME COLUMN_NAME COLUMN_POSITION
P_IDX_FULL P_INST_NO 1
P_IDX_FULL P_DRAWN_ON_BANK 2
P_IDX_FULL P_DRAWN_ON_BRN 3
P_IDX_FULL P_INST_TYPE 4
P_IDX_FULL P_DRAWN_ON_LOC 5
P_IDX_FULL P_RTN_DATE 6
P_INDX1 P_INST_NO 1
P_INDX2 P_RTN_DATE 1
P_INDX2 P_RTN_DAY_SL 2
P_INDX2 P_RTN_INS_SL 3
P_INDX3 P_REALISED_ON 1
P_INDX3 P_REALISED_DAY_SL 2
P_INDX3 P_REALISED_INS_SL 3
P_INDX4 P_REV_TO_COL_DUE_DATE 1
P_INDX4 P_REV_TO_COL_DONE_ON 2
P_INDX5 P_ARNGMNT_CREDIT_DATE 1
P_INDX6 P_POOL_POST_DATE 1
P_INDX6 P_POOL_POST_DAYSL 2
P_PK P_DEP_BNK_CODE 1
P_PK P_DEP_BRN_CODE 2
P_PK P_DEP_DATE 3
P_PK P_DEP_LCC_UCC 4
P_PK P_DEP_DAY_SL 5
P_PK P_DEP_INST_SL 6
Top 5 Timed Foreground Events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Avg
wait % DB
Event Waits Time(s) (ms) time Wait Class
DB CPU 58,454 13.1
enq: TX - row lock contention 1,095 17,691 16156 4.0 Applicatio
read by other session 1,719,661 11,392 7 2.6 User I/O
latch: cache buffers chains 264,753 10,758 41 2.4 Concurrenc
latch free 78,456 8,215 105 1.8 Other
The query comes on top in every section in AWR.Regards, -
Explain plan for running query
Hi everyone,
I come to know how to generate explain plan for a given query by giving
Explain plan for select * fro emp;
Consider a query running for 5 hrs in a session and i want to genrate explain plan for that current query in its 4th hour i dont know the sql as well
all the steps by step would be much apppreciated
like finding Current SQL then so on
Thanks
Shareef912856 wrote:
Hi everyone,
I come to know how to generate explain plan for a given query by giving
Explain plan for select * fro emp;
Consider a query running for 5 hrs in a session and i want to genrate explain plan for that current query in its 4th hour i dont know the sql as well
all the steps by step would be much apppreciated
like finding Current SQL then so on
Thanks
ShareefYOu can also use dbms_xplain to generate plan used in v$sql. like for example
SQL>SELECT SQL_ID, CHILD_NUMBER FROM V$SQL WHERE SQL_TEXT LIKE 'select * from em%';
SQL_ID CHILD_NUMBER
6kd5fkqdjb8fu 0
SQL>SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('6kd5fkqdjb8fu',0,'ALLSTATS'));If you need the actual tuntime statistics used by sql statement then you need to put hint /*+ gather_plan_statistics */ in sql ststement, something like
select /*+ gather_plan_statistics */ * from emp;
and then generate the explain plan for this
Have a look
http://hoopercharles.wordpress.com/2010/03/01/dbms_xplan-format-parameters/
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST')); -
Hi,
As per documentation i learnt, For Every SQL statement i.e Executed , it will generate 23 Executions plan for a single query. The Runtime Engine will choose the Best Execution plan for Fetch Operation.
In which Data dictionary view , do i have to check all those 23 Executions plans..
Thanksstartup wrote:
Hi,
As per documentation i learnt, For Every SQL statement i.e Executed , it will generate 23 Executions plan for a single query. The Runtime Engine will choose the Best Execution plan for Fetch Operation.
In which Data dictionary view , do i have to check all those 23 Executions plans..
Thanks
please post URL to document that says 23 Execute Plans are generated. -
Can I use a different I'd for developing on the same Mac I use for iTunes?
I Want to become an app developer but I would like to use a new account. I already have an apple I'd that I want to keep using for everything else on my Mac. Is it possible to use one for music and apps and another for developing on the same computer?
Hi Schatzie246,
Thanks for visiting Apple Support Communities.
You can create a new Apple ID for use with the Apple Developer Programs if you'd prefer:
New Apple ID
Create a new Apple ID if you have an existing iTunes Connect account, participate in the Volume Purchase Program, are enrolled in the iOS Developer Enterprise Program, or prefer to have an Apple ID dedicated
to your business transactions.
From Apple Developer: Sign in or create an Apple ID.
See this page for more information about the Apple Developer Programs:
https://developer.apple.com/support/
Best Regards,
Jeremy -
Query plan changes when query is used in CREATE TABLE AS
We've puzzled by the fact that EXPLAIN PLAN gives a much different output for a SELECT statement than it does when the same statement is used for CREATE TABLE . . . AS SELECT.
The bad part is that the CREATE TABLE version performs very badly, and that's what we want the query for.
Why does this happen? Is there a difference (from the database's point of view) between retrieving a set of rows to display to the user and putting that same set into a new table? Doesn't this make it harder to diagnose and fix query performance problems?
Here's our query:
create table query_test AS
select term, parentTerm, apidb.tab_to_string(cast(collect(trim(to_char(internal)))
as apidb.varchartab), ', ') as internal
from (
select distinct ga.organism as term,
ga.species as parentTerm,
tn.taxon_id as internal
from apidb.GeneAttributes ga, SRES.TaxonName tn, sres.Taxon t,
dots.AaSequence aas, dots.SecondaryStructure ss
where ga.organism = tn.name
and tn.taxon_id = t.taxon_id
and t.taxon_id = aas.taxon_id
and aas.aa_sequence_id = ss.aa_sequence_id
and t.rank != 'species'
union
select distinct ga.species as term,
'' as parentTerm,
ts.taxon_id as internal
from apidb.GeneAttributes ga, SRES.TaxonName tn, apidb.taxonSpecies ts,
dots.aasequence aas, dots.SecondaryStructure ss
where ga.organism = tn.name
and tn.taxon_id = ts.taxon_id
and ts.taxon_id = aas.taxon_id
and aas.aa_sequence_id = ss.aa_sequence_id
group by term,parentTerm;Without the CREATE TABLE, the plan looks like this:
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | CREATE TABLE STATEMENT | | 2911 | 5986K| | 18840 (1)| 00:03:47 |
| 1 | LOAD AS SELECT | QUERY_TEST | | | | | |
| 2 | VIEW | | 2911 | 5986K| | 18669 (1)| 00:03:45 |
| 3 | SORT GROUP BY | | 2911 | 332K| | 18660 (1)| 00:03:44 |
| 4 | VIEW | | 2911 | 332K| | 18659 (1)| 00:03:44 |
| 5 | SORT UNIQUE | | 2911 | 292K| | 18659 (6)| 00:03:44 |
| 6 | UNION-ALL | | | | | | |
|* 7 | HASH JOIN | | 2907 | 292K| 2160K| 17762 (1)| 00:03:34 |
| 8 | TABLE ACCESS FULL | GENEATTRIBUTES10650 | 40957 | 1679K| | 795 (1)| 00:00:10 |
|* 9 | HASH JOIN | | 53794 | 3204K| 1552K| 16675 (1)| 00:03:21 |
|* 10 | HASH JOIN | | 37802 | 1107K| | 12326 (1)| 00:02:28 |
|* 11 | HASH JOIN | | 37945 | 629K| | 10874 (1)| 00:02:11 |
| 12 | INDEX FAST FULL SCAN | SECONDARYSTRUCTURE_REVIX9 | 37945 | 222K| | 33 (0)| 00:00:01 |
| 13 | INDEX FAST FULL SCAN | AASEQUENCEIMP_REVIX6 | 7886K| 82M| | 10816 (1)| 00:02:10 |
|* 14 | TABLE ACCESS FULL | TAXON | 514K| 6530K| | 1450 (1)| 00:00:18 |
| 15 | TABLE ACCESS FULL | TAXONNAME | 760K| 22M| | 2721 (1)| 00:00:33 |
|* 16 | HASH JOIN | | 4 | 380 | | 886 (1)| 00:00:11 |
| 17 | NESTED LOOPS | | 730 | 64970 | | 852 (1)| 00:00:11 |
|* 18 | HASH JOIN | | 1 | 78 | | 847 (1)| 00:00:11 |
| 19 | NESTED LOOPS | | | | | | |
| 20 | NESTED LOOPS | | 17 | 612 | | 51 (0)| 00:00:01 |
| 21 | TABLE ACCESS FULL | TAXONSPECIES10646 | 12 | 60 | | 3 (0)| 00:00:01 |
|* 22 | INDEX RANGE SCAN | TAXONNAME_IND01 | 1 | | | 2 (0)| 00:00:01 |
| 23 | TABLE ACCESS BY INDEX ROWID| TAXONNAME | 1 | 31 | | 4 (0)| 00:00:01 |
| 24 | TABLE ACCESS FULL | GENEATTRIBUTES10650 | 40957 | 1679K| | 795 (1)| 00:00:10 |
|* 25 | INDEX RANGE SCAN | AASEQUENCEIMP_REVIX6 | 768 | 8448 | | 5 (0)| 00:00:01 |
| 26 | INDEX FAST FULL SCAN | SECONDARYSTRUCTURE_REVIX9 | 37945 | 222K| | 33 (0)| 00:00:01 |
Predicate Information (identified by operation id):
7 - access("GA"."ORGANISM"="TN"."NAME")
9 - access("TN"."TAXON_ID"="T"."TAXON_ID")
10 - access("T"."TAXON_ID"="TAXON_ID")
11 - access("AA_SEQUENCE_ID"="SS"."AA_SEQUENCE_ID")
14 - filter("T"."RANK"<>'species')
16 - access("AA_SEQUENCE_ID"="SS"."AA_SEQUENCE_ID")
18 - access("GA"."ORGANISM"="TN"."NAME")
22 - access("TN"."TAXON_ID"="TS"."TAXON_ID")
25 - access("TS"."TAXON_ID"="TAXON_ID")
46 rows selected.With the CREATE TABLE, the plan for the SELECT alone looks like this:
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 2 | 234 | 1786 (1)| 00:00:22 |
| 1 | SORT GROUP BY | | 2 | 234 | 1786 (1)| 00:00:22 |
| 2 | VIEW | | 2 | 234 | 1785 (1)| 00:00:22 |
| 3 | SORT UNIQUE | | 2 | 198 | 1785 (48)| 00:00:22 |
| 4 | UNION-ALL | | | | | |
|* 5 | HASH JOIN | | 1 | 103 | 949 (1)| 00:00:12 |
| 6 | NESTED LOOPS | | 199 | 19303 | 915 (1)| 00:00:11 |
| 7 | NESTED LOOPS | | 13 | 1118 | 850 (1)| 00:00:11 |
| 8 | NESTED LOOPS | | 13 | 949 | 824 (1)| 00:00:10 |
| 9 | VIEW | VW_DTP_E387155E | 13 | 546 | 797 (1)| 00:00:10 |
| 10 | HASH UNIQUE | | 13 | 546 | 797 (1)| 00:00:10 |
| 11 | TABLE ACCESS FULL | GENEATTRIBUTES10650 | 40957 | 1679K| 795 (1)| 00:00:10 |
| 12 | TABLE ACCESS BY INDEX ROWID| TAXONNAME | 1 | 31 | 3 (0)| 00:00:01 |
|* 13 | INDEX RANGE SCAN | TAXONNAME_IND02 | 1 | | 2 (0)| 00:00:01 |
|* 14 | TABLE ACCESS BY INDEX ROWID | TAXON | 1 | 13 | 2 (0)| 00:00:01 |
|* 15 | INDEX UNIQUE SCAN | PK_TAXON | 1 | | 1 (0)| 00:00:01 |
|* 16 | INDEX RANGE SCAN | AASEQUENCEIMP_REVIX6 | 15 | 165 | 5 (0)| 00:00:01 |
| 17 | INDEX FAST FULL SCAN | SECONDARYSTRUCTURE_REVIX9 | 37945 | 222K| 33 (0)| 00:00:01 |
| 18 | NESTED LOOPS | | 1 | 95 | 834 (1)| 00:00:11 |
| 19 | NESTED LOOPS | | 1 | 89 | 833 (1)| 00:00:10 |
|* 20 | HASH JOIN | | 1 | 78 | 828 (1)| 00:00:10 |
| 21 | NESTED LOOPS | | | | | |
| 22 | NESTED LOOPS | | 13 | 949 | 824 (1)| 00:00:10 |
| 23 | VIEW | VW_DTP_2AAE9FCE | 13 | 546 | 797 (1)| 00:00:10 |
| 24 | HASH UNIQUE | | 13 | 546 | 797 (1)| 00:00:10 |
| 25 | TABLE ACCESS FULL | GENEATTRIBUTES10650 | 40957 | 1679K| 795 (1)| 00:00:10 |
|* 26 | INDEX RANGE SCAN | TAXONNAME_IND02 | 1 | | 2 (0)| 00:00:01 |
| 27 | TABLE ACCESS BY INDEX ROWID| TAXONNAME | 1 | 31 | 3 (0)| 00:00:01 |
| 28 | TABLE ACCESS FULL | TAXONSPECIES10646 | 12 | 60 | 3 (0)| 00:00:01 |
|* 29 | INDEX RANGE SCAN | AASEQUENCEIMP_REVIX6 | 768 | 8448 | 5 (0)| 00:00:01 |
|* 30 | INDEX RANGE SCAN | SECONDARYSTRUCTURE_REVIX9 | 1 | 6 | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
5 - access("AA_SEQUENCE_ID"="SS"."AA_SEQUENCE_ID")
13 - access("ITEM_1"="TN"."NAME")
14 - filter("T"."RANK"<>'species')
15 - access("TN"."TAXON_ID"="T"."TAXON_ID")
16 - access("T"."TAXON_ID"="TAXON_ID")
20 - access("TN"."TAXON_ID"="TS"."TAXON_ID")
26 - access("ITEM_1"="TN"."NAME")
29 - access("TS"."TAXON_ID"="TAXON_ID")
30 - access("AA_SEQUENCE_ID"="SS"."AA_SEQUENCE_ID")
50 rows selected.Edited by: JohnI on Jul 18, 2011 2:19 PM
Edited by: JohnI on Jul 18, 2011 2:28 PMCharles Hooper wrote a series of blog entries on a similar topic some time ago: http://hoopercharles.wordpress.com/2010/12/15/select-statement-is-fast-insert-into-using-the-select-statement-is-brutally-slow-1/ (including a lot of useful comments) and two following articles. I have to confess that I did not read the posts again - but I think you will find some good ideas how to analyze the problem.
Regards
Martin Preiss -
Dynamic query plan vs normal query plan
I have a query with like operator.
DECLARE @query varchar(52)
SET @query='A12657'
IF @query IS NOT NULL
SET @query='%'+LTRIM(RTRIM(@query))+'%'SELECT eord_type_id FROM izdelek
WHERE (izd_naziv_ANG like @query OR izd_id like @query)
OPTION (RECOMPILE)
Query works 1 ms, 5 ms is for plan recompile. The execution plan is:
But if I run the same query as dynamic sql:
DECLARE @query varchar(52), @sql NVARCHAR(4000), @paramList NVARCHAR(500)
SET @query='A12657'
SELECT @paramlist = N'@query VARCHAR(52)'
if @query IS NOT NULL
SET @query='%'+LTRIM(RTRIM(@query))+'%'
SET @sql=N'SELECT eord_type_id FROM izdelek
WHERE (izd_naziv_ANG like @query OR izd_id like @query)
OPTION (RECOMPILE)'
EXEC sp_executesql @sql, @paramlist, @query
The execution plan is different and execution time is much slower - 2877 ms.
Where is the catch? What should I change that dynamic query would work the same.
What I also don't understand is key lookup at the end of the plan. Since we have clustered index seek at the beginning of the plan, the optimizer could read additional column(eord_type_id) from this index seek.
And why it is using merge since it has both columns from WHERE clause (izd_naziv_ang and izd_id) included inside index IX_izdelek. izd_id is in fact clustered key.
How can i improve this query?
But I would like to know at most, why dynamic sql is so much slower, since the query is totally the same in both cases and how to achieve that both queries have the similar execution time?First of all , why do you use LIKE operator instead of EQUAL (=). I see you are looking for exact value..
--SQL Server creates 3 execution plan rather only one
DBCC FREEPROCCACHE
GO
SELECT *
FROM Sales.SalesOrderHeader
WHERE SalesOrderID = 56000
GO
SELECT * FROM
AdventureWorks.Sales.SalesOrderHeader WHERE
SalesOrderID = 56001
GO
declare @i int
set @i = 56004
SELECT *
FROM Sales.SalesOrderHeader
WHERE SalesOrderID = @i
GO
select stats.execution_count AS exec_count,
p.size_in_bytes as [size],
[sql].[text] as [plan_text]
from sys.dm_exec_cached_plans p
outer apply sys.dm_exec_sql_text (p.plan_handle) sql
join sys.dm_exec_query_stats stats ON stats.plan_handle = p.plan_handle
GO
----This time only (we get parameterization)
DBCC FREEPROCCACHE
GO
EXEC sp_executesql N'SELECT SUM(LineTotal) AS LineTotal
FROM Sales.SalesOrderHeader H
JOIN Sales.SalesOrderDetail D ON D.SalesOrderID = H.SalesOrderID
WHERE H.SalesOrderID = @SalesOrderID', N'@SalesOrderID INT', 56000
GO
EXEC sp_executesql N'SELECT SUM(LineTotal) AS LineTotal
FROM Sales.SalesOrderHeader H
JOIN Sales.SalesOrderDetail D ON D.SalesOrderID = H.SalesOrderID
WHERE H.SalesOrderID = @SalesOrderID', N'@SalesOrderID INT', 56005
GO
select stats.execution_count AS exec_count,
LEFT([sql].[text], 80) as [plan_text]
from sys.dm_exec_cached_plans p
outer apply sys.dm_exec_sql_text (p.plan_handle) sql
join sys.dm_exec_query_stats stats ON stats.plan_handle = p.plan_handle
GO
Best Regards,Uri Dimant SQL Server MVP,
http://sqlblog.com/blogs/uri_dimant/
MS SQL optimization: MS SQL Development and Optimization
MS SQL Consulting:
Large scale of database and data cleansing
Remote DBA Services:
Improves MS SQL Database Performance
SQL Server Integration Services:
Business Intelligence
Maybe you are looking for
-
Windows 7: Trust Relationship Error - Local Administrator Account Locked.
I have 2 Windows 7 Professional machines that recently locked me out citing the "Trust Relationship between this workstation and primary domain failed". I assumed all I would have to do is log in as local administrator and remove it from the domain
-
Hi, my refurbished rMBP 15" has a stuck (white) pixel and is still under the 1 year limited warranty, can/will Apple repair it if I go to an Apple Store? I just discovered today that my MacBook has a "stuck" pixel. I read that the display has to have
-
TS3212 "invalid drive :/E "error? during itunes installation..
I have the following error during updating itunes.. Is there a way around it? Regards, Nicolaas
-
From where the VBRK-STCEG field value in the invoice header gets filled.
Hi Friends, I have a scenario in my client system. I have one sales organisation in Spain which sends a order to France based sales organisation. In the France based sales organisation the sales order will be created with sold to partner as the Spain
-
Previous Years revenue along with current year
Hi, We have a universe on top of BEX query. I am trying to query it for a particular year and the result should have the queried year revenue and revenue of previous years available. For example: if I am querying for 2010 the report should have 2010