How oracle decide whetehr to use index or full scan (statistics)
Hi Guys,
Let say i have a index on a column.
The table and index statistics has been gathered. (without histograms).
Let say i perform a select * from table where a=5;
Oracle will perform a full scan.
But from which statistics it will be able to know indeed most of the column = 5? (histograms not used)
After analyzing, we get the below:
Table Statistics :
(NUM_ROWS)
(BLOCKS)
(EMPTY_BLOCKS)
(AVG_SPACE)
(CHAIN_COUNT)
(AVG_ROW_LEN)
Index Statistics :
(BLEVEL)
(LEAF_BLOCKS)
(DISTINCT_KEYS)
(AVG_LEAF_BLOCKS_PER_KEY)
(AVG_DATA_BLOCKS_PER_KEY)
(CLUSTERING_FACTOR)
thanks
Index Column (A)
======
1
1
2
2
5
5
5
5
5
5
I have prepared some explanation and have not noticed that the topic has been marked as answered.
This my sentence is not completely true.
A column "without histograms" means that the column has only one bucket. More correct: even without histograms there are data in dba_tab_histograms which we can consider as one bucket for whole column. In fact these data are retrieved from hist_head$, not from histgrm$ as usual buckets.
Technically there is no any buckets without gathered histograms.
Let's create a table with skewed data distribution.
SQL> create table t as
2 select least(rownum,3) as val, '*' as pad
3 from dual
4 connect by level <= 1000000;
Table created
SQL> create index idx on t(val);
Index created
SQL> select val, count(*)
2 from t
3 group by val;
VAL COUNT(*)
1 1
2 1
3 999998So, we have table with very skewed data distribution.
Let's gather statistics without histograms.
SQL> exec dbms_stats.gather_table_stats( user, 'T', estimate_percent => 100, method_opt => 'for all columns size 1', cascade => true);
PL/SQL procedure successfully completed
SQL> select blocks, num_rows from dba_tab_statistics
2 where table_name = 'T';
BLOCKS NUM_ROWS
3106 1000000
SQL> select blevel, leaf_blocks, clustering_factor
2 from dba_ind_statistics t
3 where table_name = 'T'
4 and index_name = 'IDX';
BLEVEL LEAF_BLOCKS CLUSTERING_FACTOR
2 4017 3107
SQL> select column_name,
2 num_distinct,
3 density,
4 num_nulls,
5 low_value,
6 high_value
7 from dba_tab_col_statistics
8 where table_name = 'T'
9 and column_name = 'VAL';
COLUMN_NAME NUM_DISTINCT DENSITY NUM_NULLS LOW_VALUE HIGH_VALUE
VAL 3 0,33333333 0 C102 C104So, Oracle suggests that values between 1 and 3 (raw C102 and C104) are distributed uniform and the density of the distribution is 0.33.
Let's try to explain plan
SQL> explain plan for
2 select --+ no_cpu_costing
3 *
4 from t
5 where val = 1
6 ;
Explained
SQL> @plan
| Id | Operation | Name | Rows | Cost |
| 0 | SELECT STATEMENT | | 333K| 300 |
|* 1 | TABLE ACCESS FULL| T | 333K| 300 |
Predicate Information (identified by operation id):
1 - filter("VAL"=1)
Note
- cpu costing is off (consider enabling it)Below is an excerpt from trace 10053
BASE STATISTICAL INFORMATION
Table Stats::
Table: T Alias: T
#Rows: 1000000 #Blks: 3106 AvgRowLen: 5.00
Index Stats::
Index: IDX Col#: 1
LVLS: 2 #LB: 4017 #DK: 3 LB/K: 1339.00 DB/K: 1035.00 CLUF: 3107.00
SINGLE TABLE ACCESS PATH
BEGIN Single Table Cardinality Estimation
Column (#1): VAL(NUMBER)
AvgLen: 3.00 NDV: 3 Nulls: 0 Density: 0.33333 Min: 1 Max: 3
Table: T Alias: T
Card: Original: 1000000 Rounded: 333333 Computed: 333333.33 Non Adjusted: 333333.33
END Single Table Cardinality Estimation
Access Path: TableScan
Cost: 300.00 Resp: 300.00 Degree: 0
Cost_io: 300.00 Cost_cpu: 0
Resp_io: 300.00 Resp_cpu: 0
Access Path: index (AllEqRange)
Index: IDX
resc_io: 2377.00 resc_cpu: 0
ix_sel: 0.33333 ix_sel_with_filters: 0.33333
Cost: 2377.00 Resp: 2377.00 Degree: 1
Best:: AccessPath: TableScan
Cost: 300.00 Degree: 1 Resp: 300.00 Card: 333333.33 Bytes: 0Cost of FTS here is 300 and cost of Index Range Scan here is 2377.
I have disabled cpu costing, so selectivity does not affect the cost of FTS.
cost of Index Range Scan is calculated as
blevel + (leaf_blocks * selectivity + clustering_factor * selecivity) = 2 + (4017*0.33333 + 3107*0.33333) = 2377.
Oracle considers that it has to read 2 root/branch blocks of the index, 1339 leaf blocks of the index and 1036 blocks of the table.
Pay attention that selectivity is the major component of the cost of the Index Range Scan.
Let's try to gather histograms:
SQL> exec dbms_stats.gather_table_stats( user, 'T', estimate_percent => 100, method_opt => 'for columns val size 3', cascade => true);
PL/SQL procedure successfully completedIf you look at dba_tab_histograms you will see following
SQL> select endpoint_value,
2 endpoint_number
3 from dba_tab_histograms
4 where table_name = 'T'
5 and column_name = 'VAL'
6 ;
ENDPOINT_VALUE ENDPOINT_NUMBER
1 1
2 2
3 1000000ENDPOINT_VALUE is the column value (in number for any type of data) and ENDPOINT_NUMBER is cumulative number of rows.
Number of rows for any ENDPOINT_VALUE = ENDPOINT_NUMBER for this ENDPOINT_VALUE - ENDPOINT_NUMBER for the previous ENDPOINT_VALUE.
explain plan and 10053 trace of the same query:
| Id | Operation | Name | Rows | Cost |
| 0 | SELECT STATEMENT | | 1 | 4 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 4 |
|* 2 | INDEX RANGE SCAN | IDX | 1 | 3 |
Predicate Information (identified by operation id):
2 - access("VAL"=1)
Note
- cpu costing is off (consider enabling it)
BASE STATISTICAL INFORMATION
Table Stats::
Table: T Alias: T
#Rows: 1000000 #Blks: 3106 AvgRowLen: 5.00
Index Stats::
Index: IDX Col#: 1
LVLS: 2 #LB: 4017 #DK: 3 LB/K: 1339.00 DB/K: 1035.00 CLUF: 3107.00
SINGLE TABLE ACCESS PATH
BEGIN Single Table Cardinality Estimation
Column (#1): VAL(NUMBER)
AvgLen: 3.00 NDV: 3 Nulls: 0 Density: 5.0000e-07 Min: 1 Max: 3
Histogram: Freq #Bkts: 3 UncompBkts: 1000000 EndPtVals: 3
Table: T Alias: T
Card: Original: 1000000 Rounded: 1 Computed: 1.00 Non Adjusted: 1.00
END Single Table Cardinality Estimation
Access Path: TableScan
Cost: 300.00 Resp: 300.00 Degree: 0
Cost_io: 300.00 Cost_cpu: 0
Resp_io: 300.00 Resp_cpu: 0
Access Path: index (AllEqRange)
Index: IDX
resc_io: 4.00 resc_cpu: 0
ix_sel: 1.0000e-06 ix_sel_with_filters: 1.0000e-06
Cost: 4.00 Resp: 4.00 Degree: 1
Best:: AccessPath: IndexRange Index: IDX
Cost: 4.00 Degree: 1 Resp: 4.00 Card: 1.00 Bytes: 0Pay attention on selectivity, ix_sel: 1.0000e-06
Cost of the FTS is still the same = 300,
but cost of the Index Range Scan is 4 now: 2 root/branch blocks + 1 leaf block + 1 table block.
Thus, conclusion: histograms allows to calculate selectivity more accurate. The aim is to have more efficient execution plans.
Alexander Anokhin
http://alexanderanokhin.wordpress.com/
Similar Messages
-
How to make sql to use index/make to query to perform better
Hi,
I have 2 sql query which results the same.
But both has difference in SQL trace.
create table test_table
(u_id number(10),
u_no number(4),
s_id number(10),
s_no number(4),
o_id number(10),
o_no number(4),
constraint pk_test primary key(u_id, u_no));
insert into test_table(u_id, u_no, s_id, s_no, o_id, o_no)
values (2007030301, 1, 1001, 1, 2001, 1);
insert into test_table(u_id, u_no, s_id, s_no, o_id, o_no)
values (2007030302, 1, 1001, 1, 2001, 2);
insert into test_table(u_id, u_no, s_id, s_no, o_id, o_no)
values (2007030303, 1, 1001, 1, 2001, 3);
insert into test_table(u_id, u_no, s_id, s_no, o_id, o_no)
values (2007030304, 1, 1001, 1, 2001, 4);
insert into test_table(u_id, u_no, s_id, s_no, o_id, o_no)
values (2007030305, 1, 1002, 1, 1001, 2);
insert into test_table(u_id, u_no, s_id, s_no, o_id, o_no)
values (2007030306, 1, 1002, 1, 1002, 1);
commit;
CREATE INDEX idx_test_s_id ON test_table(s_id, s_no);
set autotrace on
select s_id, s_no, o_id, o_no
from test_table
where s_id <> o_id
and s_no <> o_no
union all
select o_id, o_no, s_id, s_no
from test_table
where s_id <> o_id
and s_no <> o_no;
Execution Plan
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=8 Bytes=416)
1 0 UNION-ALL
2 1 TABLE ACCESS (FULL) OF 'TEST_TABLE' (TABLE) (Cost=3 Card=4 Bytes=208)
3 1 TABLE ACCESS (FULL) OF 'TEST_TABLE' (TABLE) (Cost=3 Card=4 Bytes=208)
Statistics
223 recursive calls
2 db block gets
84 consistent gets
0 physical reads
0 redo size
701 bytes sent via SQL*Net to client
508 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
5 sorts (memory)
0 sorts (disk)
8 rows processed
-- i didnt understand why the above query is not using the index idx_test_s_id.
-- But still it is faster
select s_id, s_no, o_id, o_no
from test_table
where (u_id, u_no) in
(select u_id, u_no from test_table
minus
select u_id, u_no from test_table
where s_id = o_id
or s_no = o_no)
union all
select o_id, o_no, s_id, s_no
from test_table
where (u_id, u_no) in
(select u_id, u_no from test_table
minus
select u_id, u_no from test_table
where s_id = o_id
or s_no = o_no);
Execution Plan
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=16 Card=2 Bytes=156)
1 0 UNION-ALL
2 1 FILTER
3 2 TABLE ACCESS (FULL) OF 'TEST_TABLE' (TABLE) (Cost=3 Card=6 Bytes=468)
4 2 MINUS
5 4 INDEX (UNIQUE SCAN) OF 'PK_TEST' (INDEX (UNIQUE)) (Cost=1 Card=1 Bytes=26)
6 4 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE' (TABLE) (Cost=2 Card=1 Bytes=78)
7 6 INDEX (UNIQUE SCAN) OF 'PK_TEST' (INDEX (UNIQUE)) (Cost=1 Card=1)
8 1 FILTER
9 8 TABLE ACCESS (FULL) OF 'TEST_TABLE' (TABLE) (Cost=3 Card=6 Bytes=468)
10 8 MINUS
11 10 INDEX (UNIQUE SCAN) OF 'PK_TEST' (INDEX (UNIQUE)) (Cost=1 Card=1 Bytes=26)
12 10 TABLE ACCESS (BY INDEX ROWID) OF 'TEST_TABLE' (TABLE) (Cost=2 Card=1 Bytes=78)
13 12 INDEX (UNIQUE SCAN) OF 'PK_TEST' (INDEX (UNIQUE)) (Cost=1 Card=1)
Statistics
53 recursive calls
8 db block gets
187 consistent gets
0 physical reads
0 redo size
701 bytes sent via SQL*Net to client
508 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
4 sorts (memory)
0 sorts (disk)
8 rows processed
-- The above query is using index PK_TEST. But still it has FULL SCAN to the
-- table two times it has the more cost.
1st query --> SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=8 Bytes=416)
2nd query --> SELECT STATEMENT Optimizer=ALL_ROWS (Cost=16 Card=2 Bytes=156)
My queries are:
1) performance wise which query is better?
2) how do i make the 1st query to use an index
3) is there any other method to get the same result by using any index
Appreciate your immediate help.
Best regards
MuthuHi William
Nice...it works.. I have added "o_id" and "o_no" are in part of the index
and now the query uses the index
Execution Plan
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=8 Bytes=416)
1 0 UNION-ALL
2 1 INDEX (FULL SCAN) OF 'IDX_TEST_S_ID' (INDEX) (Cost=1 Card=4 Bytes=208)
3 1 INDEX (FULL SCAN) OF 'IDX_TEST_S_ID' (INDEX) (Cost=1 Card=4 Bytes=208)
Statistics
7 recursive calls
0 db block gets
21 consistent gets
0 physical reads
0 redo size
701 bytes sent via SQL*Net to client
507 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
8 rows processed
But my questions are:
1) In a where clause, if "<>" condition is used, then, whether the system will use the index. Because I have observed in several situations even though the column in where clause is indexed, since the where condition is "like" or "is null/is not null"
then the index is not used. Same as like this, i assumed, if we use <> then indexes will not be used. Is it true?
2) Now, after adding "o_id" and "o_no" columns to the index, the Execution plan is:
Execution Plan
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=8 Bytes=416)
1 0 UNION-ALL
2 1 INDEX (FULL SCAN) OF 'IDX_TEST_S_ID' (INDEX) (Cost=1 Card=4 Bytes=208)
3 1 INDEX (FULL SCAN) OF 'IDX_TEST_S_ID' (INDEX) (Cost=1 Card=4 Bytes=208)
Before it was :
Execution Plan
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=8 Bytes=416)
1 0 UNION-ALL
2 1 TABLE ACCESS (FULL) OF 'TEST_TABLE' (TABLE) (Cost=3 Card=4 Bytes=208)
3 1 TABLE ACCESS (FULL) OF 'TEST_TABLE' (TABLE) (Cost=3 Card=4 Bytes=208)
Difference only in Cost (reduced), not in Card, Bytes.
Can you explain, how can i decide which makes the performace better (Cost / Card / Bytes). Full Scan / Range Scan?
On statistics also:
Before:
Statistics
52 recursive calls
0 db block gets
43 consistent gets
0 physical reads
0 redo size
701 bytes sent via SQL*Net to client
507 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
8 rows processed
After:
Statistics
7 recursive calls
0 db block gets
21 consistent gets
0 physical reads
0 redo size
701 bytes sent via SQL*Net to client
507 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
8 rows processed
Difference in recursive calls & consistent gets.
Which one shows the query with better performance?
Please explain..
Regards
Muthu -
How to decide whether to use a cube or dso?
Hi,
If any requirment is given ,Based on what conditions we decide which data target(i.e a cube or dso) to be used ?
As of my knowledge,
1) DSO has the property of Over write option and cube have additive property.
2) DSO can have delta records and cube can not have.
Do we need consider these also?while we decide to load?
help me how to decide the data target for a particular requirment
Regards
Naresh.Hi,
If you have to report on a data target, you should always use Cube (give us better performance).
For intermediate storage, we use DSO.
Another thing is that DSO can also be used in additive mode. Regarding Delta, cube can have delta loads and can also provide delta to another target.
Regards,
Gaurav -
How is it possible to use Index Seek for LIKE %search-string% case?
Hello,
I have the following SP:
CREATE PROCEDURE dbo.USP_SAMPLE_PROCEDURE(@Beginning nvarchar(15))
AS
SELECT * FROM HumanResources.Employee
WHERE NationalIDNumber LIKE @Beginning + N'%';
GO
If I run the sp first time with param: N'94', then the following plan is generated and added to the cache:
SQL Server "sniffs" the input value (94) when compiling the query. So for this param using Index Seek for AK_Employee_NationalIDNumber index will be the best option. On the other hand, the query plan should be generic enough to be able to handle
any values specified in the @Beginning param.
If I call the sp with @Beginning =N'%94':
EXEC dbo.USP_SAMPLE_PROCEDURE N'%94'
I see the same execution plan as above. The question is how is it possible to reuse this execution plan in this case? To be more precise, how
Index Seek can be used in case LIKE %search-string% case. I expected that
ONLY Index Scan operation can be used here.
AlexeyThe key is that the index seek operator includes both seek (greater than and less than) and a predicate (LIKE). With the leading wildcard, the seek is effectively returning all rows just like a scan and the filter returns only rows matching
the LIKE expression.
Do you want to say that in case of leading wildcard, expressions Expr1007 and Expr1008 (see image below) calculated such a way that
Seek Predicates retrieve all rows from the index. And only
Predicate does the real job by taking only rows matching the Like expression? If this is the case, then it explains how
Index Seek can be used to resolve such queries: LIKE N'%94'.
However, it leads me to another question: Since
Index Seek in
this particular case scans
all the rows, what is the difference between
Index Seek and Index Scan?
According to
MSDN:
The Index Seek operator uses the seeking ability of indexes to retrieve rows from a nonclustered index.
The storage engine uses the index to process
only those rows that satisfy the SEEK:() predicate. It optionally may include a WHERE:() predicate, which the storage engine will evaluate against all rows that satisfy the SEEK:() predicate (it does not use the indexes to do this).
The Index Scan operator retrieves
all rows from the nonclustered index specified in the Argument column. If an optional WHERE:() predicate appears in the Argument column, only those rows that satisfy the predicate are returned.
It seems like Index Scan is a special case of Index Seek,
which means that when we see Index Seek in the execution plan, it does NOT mean that storage engine does NOT scan all rows. Right?
Alexey -
Query tuning and how to force table to use index?
Dear Experts,
i have two (2) question regarding performance during DRL.
Question # 1
There is a column name co_id in every transaction table. DBA suggest me to add [co_id='KPG'] in every clause which forces query to use index, resulting immediate processing. As an index was created for each table on the co_id column.
Please note that co_id has constant value 'KPG' through out the table. is it make sense to add that column in where caluse like
select a,b,c from tab1
where a='89' and co_id='KPG'
Question # 2
if i am using a column name in where clause having index on it and that column is not in my column list does it restrict query for full table scan. like
select a,b,c,d from tabletemp
where e='ABC';
Thanks in advance
Edited by: Fiz Dosani on Mar 27, 2009 12:00 PMFiz Dosani wrote:
Dear Experts,
i have two (2) question regarding performance during DRL.
Question # 1
There is a column name co_id in every transaction table. DBA suggest me to add [co_id='KPG'] in every clause which forces query to use index, resulting immediate processing. As an index was created for each table on the co_id column.
Please note that co_id has constant value 'KPG' through out the table. is it make sense to add that column in where caluse like
select a,b,c from tab1
where a='89' and co_id='KPG'If co_id is always 'KPG' it is not needed to add this condition to the table. It would be very stupid to add an (normal) index on that column. An index is used to reduce the resultset of a query by storing the values and the rowids in a specified order. When all the values are equal and index justs makes all dml operations slower without makeing any select faster.
And of cause the CBO is clever enough not to use such a index.
>
Question # 2
if i am using a column name in where clause having index on it and that column is not in my column list does it restrict query for full table scan. like
select a,b,c,d from tabletemp
where e='ABC';
Yes this is possible. However it depends from a few things.
1) How selective this condition is. In general an index will be used when selectivity is less than 5%. This factor depends a bit on the database version. it means that when less then 5% of your rows have the value 'ABC' then an index access will be faster than the full table scan.
2) Are the statistics up to date. The cost based optimizer (CBO) needs to know how many values are in that table, in the columns, in that index to make a good decision bout using an index access or a full table scan. Often one forgets to create statistics for freshly created data as in temptables.
Edited by: Sven W. on Mar 27, 2009 8:53 AM -
How to write the query using Index
Hi All,
I have to fetch the records from Database table using Index, how can i write the query using Index. Can any body plz send me the sample code.
Help Me,
Balu.Hi,
See the below Example.
select * from vbak up to 100 rows
into table t_vbak
where vbeln > v_vbeln.
sort t_vbak by vbeln descending.
read table t_vbak index 1.
Regards,
Ram
Pls reward points if helpful. -
Oracle SGA benefits of using indexes
Goo day people,
We have been having performance issues and then the SGA was not sized coprrectely.
The size of the SGA was 720mb so we then pushed it to 4 gig which I blv is enough.
We then did a run of the tuning advisory on the top sql queries that were top one,
the advisor then pointed on that we need to use indexes on those queries .
We then advised the developers that they need to use indexes as it will improve
performance .. This morning the ADDM pointed out that we need to up the sga
to 5 Gig and I dont see this a solution to the problem.
I need to find a note on what benefits does using indexes have on the SGA and the overall perfomance
so that I can show the business that increasing the SGA wont solve the problem.
See screen shot below
erformance Finding Details:
Database Time (minutes) 33.8
Period Start Time 10-Aug-2010 10:00:11 o'clock SAST
Period Duration (minutes) 60.2
Task Owner SYS
Task Name ADDM:1511773678_1_28498
Average Active Sessions 0.6
Finding The SGA was inadequately sized, causing additional I/O or hard parses.
Impact (minutes) 14.4
Impact (%) [64] [86] 42.8
Recommendations
Show All Details | Hide All Details
Details Category Benefit (%) [Sorted in descending order]
[Select to hide information] Hide
DB Configuration [64] [86] 42.8
Action Increase the size of the SGA by setting the parameter "sga_target" to 5120 M.
Thanks
Sibusiso
Edited by: 787473 on 10-Aug-2010 02:35We have been having performance issues and then the SGA was not sized coprrectely.
The size of the SGA was 720mb so we then pushed it to 4 gig which I blv is enough.
We then did a run of the tuning advisory on the top sql queries that were top one,
the advisor then pointed on that we need to use indexes on those queries .
We then advised the developers that they need to use indexes as it will improve
performance .. Yes. As those queries must be missing indexes that would prove to be beneficial. So need to take it query by query and created the required indexes.
This morning the ADDM pointed out that we need to up the sga
to 5 Gig and I dont see this a solution to the problem.
I need to find a note on what benefits does using indexes have on the SGA and the overall perfomance
so that I can show the business that increasing the SGA wont solve the problem.
See screen shot below
erformance Finding Details:
Database Time (minutes) 33.8
Period Start Time 10-Aug-2010 10:00:11 o'clock SAST
Period Duration (minutes) 60.2
Task Owner SYS
Task Name ADDM:1511773678_1_28498
Average Active Sessions 0.6
Finding The SGA was inadequately sized, causing additional I/O or hard parses.
Impact (minutes) 14.4
Impact (%) [64] [86] 42.8
Recommendations
Show All Details | Hide All Details
Details Category Benefit (%) [Sorted in descending order]
[Select to hide information] Hide
DB Configuration [64] [86] 42.8
Action Increase the size of the SGA by setting the parameter "sga_target" to 5120 M.One of the biggest impact of indexes (if they fit in the scenario) is in reducing the IO (by avoiding full table scans). Reduced IO means faster system. Absence of indexes would mean that you read lots of data into the memory [buffer cache] and data would flush out quickly too (to make space for the new data), resulting in more IO. So having indexes in place means you only read as much amount of data as required and frequently accessed data stays in the memory.
Kinda incomplete answer...Lets wait for other experts' comments :)
Edited by: amardeep.sidhu on Aug 10, 2010 3:23 PM -
Index vs Full Scan - Parallelism
Hi everyone, i have an problem my scenario is a plataform Linux x64 bits in RAC 10gR2 (10.2.0.5) and we are migrating to RAC 11gR2 (11.2.0.3.3) in AIX 7.1 and my query: Update movimientos set ESTADOENCOLADO = :"SYS_B_0" where tipoproceso = :"SYS_B_1" and ESTADOENCOLADO = :"SYS_B_2"; in my Oracle 10g uses an index in the table MOVIMIENTOS and in the Oracle 11g the optimizer takes a FULL SCAN.
In both database server the statistics are updated with estimate 100% even the system statistics, fixed tables and data dictionary are taken its statistics.
I review the cost in both plans in Oracle 11g (with a full scan and other using a hint to index) and the full scan plan has less cost that the index. My db_file_multiblock_read_count is not set up, but in the Oracle 10g i see a value of 16 and in the 11g i see a value dinamic of 192. Understand that it too helps an uses a full scan.
The problem is that the query taken in Oracle 10g 20 minutes, but in the Oracle 11g with full scan 1.4 h whereas with a hint takes too 20 minutes.
I use the advisor tuning and no recommendations.
So basicaly i fix it modifily my parameter optimizer_index_cost_adj to 80 and it works well.
My doubt is why Oracle11gR2 says me that a full scan is faster than take an index when in the real live it is not working in this mode. I need some posible reasons please.
Thank you very much if somebody can help me with some tip or idea.
Regards>
My doubt is why Oracle11gR2 says me that a full scan is faster than take an index when in the real live it is not working in this mode. I need some posible reasons please.
>
Well if you can't figure it out by looking at the plans what makes you think anyone can figure it out without looking at them?
We have no idea what the plans contain. Post the plans, record counts for the table(s) involved, record counts for any filter predicates and the other information needed. See the FAQ for how to post a tuning request and the information needed. -
How Oracle tables can be used to display Chinese/Japanese characters
If anyone knows how to display Chinese/Japanese characters from Oracle tables please reply this email. Thanks.
Regards,
Prestonhi
->Also please let me know how the Oracle Lite is licenced if I have 300 odd users of this offline applications
you should speak to your local oracle rep about that, for us for example they gave a pretty cheap packet for olite 10gr3+ 11g repository
->need to use only database part of Oracle Lite and not mobile server.
you cant do that. mobile server is the application server that handles the synchronization process from the server side. when a client tries to sync he actually connects to the mobile server and asks for the database changes , the mobile server know what the client must get so he packs it and give it to him
->you can ofc make lightweight .net apps using olite. we make olite apps even for wince handhelds. so yes ofcourse you can. olite had a win32 client also.
->can it run from usb.
ok here to be honest ive never tried that myself, looks kinda weird as a requirement to be honest but i dont see why it shouldnt run. if you set up the paths correctly you shouldnt have a problem i think.
->offline application will have more or less similar data entry forms and storage structure
yes ofcourse , if i have 3 tables in server i can choose to have 2(or all ) of them on the client too. i can even separate which client gets what. for instance if client a sells houses in new york he will get only the house table rows for new york. if another sells for chicago he will get those instead and etc.
->all client apps are offline and sync periodically (when you choose) to the server -
Not using Index when SDO_RELATE in Spatial Query is used in LEFT OUTER JOIN
I want to know for every City (Point geometry) in which Municipality (Polygon geometry) it is.
Some cities will not be covered by any municipality (as there is no data for it), so its municipality name should be blank in the result
We have 4942 cities (point geometries)
and 500 municipalities (polygon geometry)
SELECT T1.NAME as City, T2.NAME as Municipality
FROM CITY T1
LEFT OUTER JOIN MUNICIPALITY T2 ON SDO_RELATE(T1.GEOM, T2.GEOM, 'MASK=ANYINTERACT') = 'TRUE'The explain plan for this query is:
SELECT STATEMENT
FILTER
Filter Predicates
MDSYS.SDO_RTREE_RELATE(T1.GEOM, T2.GEOM, 'mask=ANYINTERACT querytype=window ') = 'TRUE'
MERGE JOIN
TABLE ACCESS CITY FULL 11
BUFFER SORT 100605
TABLE ACCESS MUNICIPALITY FULL 20So the cost is in the BUFFER (whatever that is), it takes +2000 seconds to run this, it is not using the spatial index.
And we are not getting all rows, but only the ones interacting with a municipality, e.g. 2436 rows.
But I want all rows, including the ones not interacting with any Municipality.
When we want only those cities that actually are in a municipality, I use a different query and it will use the index.
SELECT T1.NAME as City, T2.NAME as Municipality
FROM CITY T1, MUNICIPALITY T2
WHERE SDO_RELATE(T1.GEOM, T2.GEOM, 'MASK=ANYINTERACT') = 'TRUE'I get (only) 2436 rows (as expected) in 5 seconds (it is fast) and the explain plan shows it is using the spatial index.
But in this case, I am not getting any cities not inside any municipality (of course)
SELECT STATEMENT
NESTED LOOPS
TABLE ACCESS MUNICIPALITY FULL 22
TABLE ACCESS CITY BY INDEX ROWID 22
DOMAIN INDEX CITY_SDX 0
Access Predicates
MDSYS.SDO_RTREE_RELATE(T1.GEOM, T2.GEOM, 'mask=ANYINTERACT querytype=window ') = 'TRUE'I always thought a LEFT OUTER JOIN would return all rows from the Table, whatever happens in the next,
but it seems the query has been rewritten so that it is now using a Filter Predicate in the end, which filters those geometries having no interaction.
As an example I also do thing alphanumerically, I do get 4942 rows, including the ones which have no Municipality name.
In this case the names must match, so its only for testing if the LEFT OUTER JOIN returns stuff correctly, which it does in this case.
SELECT T1.NAME as City, T2.NAME as Municipality
FROM CITY T1
LEFT OUTER JOIN MUNICIPALITY T2 ON T1.NAME = T2.NAMEIs this an Oracle Spatial bug, e.g. not return 4942 rows, but only 2436 rows on the first query?
Note all tests performed on Oracle 11g R2 (11.2.0.1.0)Patrick,
Even so, your geoms in the relate were the wrong way around.
Also, I don't recall you saying (or showing) that you wanted the municipality geometry returned. Still,
no matter, easy to do.
Here are some additional suggestions. I don't have your data so I have had to use some of my own.
set serveroutput on timing on autotrace on
SELECT T1.SPECIES as City,
(SELECT T2.ADMIN_NAME FROM AUSTRALIAN_STATES T2 WHERE SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE') as Municipality,
(SELECT T2.GEOM FROM AUSTRALIAN_STATES T2 WHERE SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE') as geom
FROM GUTDATA T1;
762 rows selected
Elapsed: 00:00:21.656
Plan hash value: 2160035213
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 762 | 49530 | 5 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| AUSTRALIAN_STATES | 1 | 115 | 0 (0)| 00:00:01 |
|* 2 | DOMAIN INDEX | AUSTRALIAN_STATES_GEOM_SPX | | | 0 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| AUSTRALIAN_STATES | 1 | 115 | 0 (0)| 00:00:01 |
|* 4 | DOMAIN INDEX | AUSTRALIAN_STATES_GEOM_SPX | | | 0 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | GUTDATA | 762 | 49530 | 5 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"(:B1,10000,0.5,'UNIT=M'))='TRUE')
4 - access("MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"(:B1,10000,0.5,'UNIT=M'))='TRUE')
Statistics
7 user calls
24576 physical read total bytes
0 physical write total bytes
0 spare statistic 3
0 commit cleanout failures: cannot pin
0 TBS Extension: bytes extended
0 total number of times SMON posted
0 SMON posted for undo segment recovery
0 SMON posted for dropping temp segment
0 segment prealloc tasksThe above can look messy as you add more (SELECT ...) attributes, but is is fast (though can't use in Materialized Views).
/* The set of all cities not in municipalities */
SELECT T1.SPECIES as City,
cast(null as varchar2(42)) as municipality,
cast(null as sdo_geometry) as geom
FROM GUTDATA T1
WHERE NOT EXISTS (SELECT 1
FROM AUSTRALIAN_STATES T2
WHERE SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE')
UNION ALL
/* The set of all cities in municipalities */
SELECT T1.SPECIES as City,
T2.ADMIN_NAME as Municipality,
T2.GEOM as geom
FROM GUTDATA T1
INNER JOIN
AUSTRALIAN_STATES T2 ON (SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE');
762 rows selected
Elapsed: 00:00:59.953
Plan hash value: 2854682795
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 99 | 13450 | 38 (87)| 00:00:01 |
| 1 | UNION-ALL | | | | | |
|* 2 | FILTER | | | | | |
| 3 | TABLE ACCESS FULL| GUTDATA | 762 | 49530 | 5 (0)| 00:00:01 |
|* 4 | DOMAIN INDEX | AUSTRALIAN_STATES_GEOM_SPX | | | 0 (0)| 00:00:01 |
| 5 | NESTED LOOPS | | 61 | 10980 | 33 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL| AUSTRALIAN_STATES | 8 | 920 | 3 (0)| 00:00:01 |
|* 7 | TABLE ACCESS FULL| GUTDATA | 8 | 520 | 4 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter( NOT EXISTS (SELECT 0 FROM "AUSTRALIAN_STATES" "T2" WHERE "MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"(:B1,10000,0.5,'UNIT=M'))='TRUE'))
4 - access("MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"(:B1,10000,0.5,'UNIT=M'))='TRUE')
7 - filter("MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"("T1"."GEOM",10000,0.5,'UNIT=M'))='TRUE')
Statistics
7 user calls
131072 physical read total bytes
0 physical write total bytes
0 spare statistic 3
0 commit cleanout failures: cannot pin
0 TBS Extension: bytes extended
0 total number of times SMON posted
0 SMON posted for undo segment recovery
0 SMON posted for dropping temp segment
0 segment prealloc tasksMuch slower but Materialized View friendly.
This one is a bit more "natural" but still slower than the first.
set serveroutput on timing on autotrace on
/* The set of all cities in municipalities */
WITH municipal_cities As (
SELECT T1.ID as City,
T2.ADMIN_NAME as Municipality,
T2.GEOM as geom
FROM GUTDATA T1
INNER JOIN
AUSTRALIAN_STATES T2 ON (SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE')
SELECT T1.ID as City,
T2.Municipality as Municipality,
T2.GEOM as geom
FROM GUTDATA T1
LEFT OUTER JOIN
municipal_cities T2
ON (T2.CITY = T1.ID);
762 rows selected
Elapsed: 00:00:50.228
Plan hash value: 745978991
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 762 | 44196 | 36 (3)| 00:00:01 |
|* 1 | HASH JOIN RIGHT OUTER| | 762 | 44196 | 36 (3)| 00:00:01 |
| 2 | VIEW | | 61 | 3294 | 33 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 61 | 10980 | 33 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | AUSTRALIAN_STATES | 8 | 920 | 3 (0)| 00:00:01 |
|* 5 | TABLE ACCESS FULL | GUTDATA | 8 | 520 | 4 (0)| 00:00:01 |
| 6 | INDEX FAST FULL SCAN| GUTDATA_ID_PK | 762 | 3048 | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("T2"."CITY"(+)="T1"."ID")
5 - filter("MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"("T1"."GEOM",10000,0.5,'UNIT=M'))='TRUE')
Statistics
7 user calls
49152 physical read total bytes
0 physical write total bytes
0 spare statistic 3
0 commit cleanout failures: cannot pin
0 TBS Extension: bytes extended
0 total number of times SMON posted
0 SMON posted for undo segment recovery
0 SMON posted for dropping temp segment
0 segment prealloc tasksFinally, the Pièce de résistance: trick the LEFT OUTER JOIN operator...
set serveroutput on timing on autotrace on
SELECT T1.SPECIES as City,
T2.ADMIN_NAME as Municipality,
T2.GEOM as geom
FROM GUTDATA T1
LEFT OUTER JOIN
AUSTRALIAN_STATES T2
ON (t2.admin_name = to_char(t1.ID) OR
SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE');
762 rows selected
Elapsed: 00:00:50.273
Plan hash value: 158854308
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 762 | 92964 | 2294 (1)| 00:00:28 |
| 1 | NESTED LOOPS OUTER | | 762 | 92964 | 2294 (1)| 00:00:28 |
| 2 | TABLE ACCESS FULL | GUTDATA | 762 | 49530 | 5 (0)| 00:00:01 |
| 3 | VIEW | | 1 | 57 | 3 (0)| 00:00:01 |
|* 4 | TABLE ACCESS FULL| AUSTRALIAN_STATES | 1 | 115 | 3 (0)| 00:00:01 |
Predicate Information (identified by operation id):
4 - filter("T2"."ADMIN_NAME"=TO_CHAR("T1"."ID") OR
"MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"("T1"."GEOM",10000,0.5,'UNIT=M'))='TRUE')
Statistics
7 user calls
0 physical read total bytes
0 physical write total bytes
0 spare statistic 3
0 commit cleanout failures: cannot pin
0 TBS Extension: bytes extended
0 total number of times SMON posted
0 SMON posted for undo segment recovery
0 SMON posted for dropping temp segment
0 segment prealloc tasksTry these combinations to see what works for you.
Interestingly, for me, the following returns absolutely nothing.
SELECT T1.SPECIES as City,
T2.ADMIN_NAME as Municipality
FROM GUTDATA T1
LEFT OUTER JOIN
AUSTRALIAN_STATES T2
ON (SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE')
MINUS
SELECT T1.SPECIES as City,
T2.ADMIN_NAME as Municipality
FROM GUTDATA T1
LEFT OUTER JOIN
AUSTRALIAN_STATES T2
ON (t2.admin_name = to_char(t1.ID) OR
SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE');(I leave it to you to see if you can see why as the LEFT OUTER JOIN seems to be working correctly for me but I am not going to dedicate time to detailed checking of results.)
Note all tests performed on Oracle 11g R2 (11.2.0.1.0)
If you get the answer you want: mark the post as answered to assign points.
regards
Simon -
select *
from hrm_career x
WHERE x.begin_date = ( SELECT MAX(begin_date)
FROM hrm_career y
WHERE y.employee_id = x.employee_id AND
begin_date <= SYSDATE AND
primary_job = 'Y') AND
x.primary_job = 'Y'
I have the above query which is not using the index created on the BEGIN_DT column
I tried to force using still not using
but when i apply a value say
select *
from hrm_career x
WHERE x.begin_date ='10-20-2007'
It is using index and resulting in very fast response
Can some throw some ideas on it...
Where should i look into here ..SQL> set autotrace traceonly
SQL> select *
2 from hrm_career x
3 WHERE x.begin_date = ( SELECT MAX(begin_date)
4 FROM hrm_career y
5 WHERE y.employee_id = x.employee_id AND
6 begin_date <= SYSDATE AND
7 primary_job = 'Y') AND
8 x.primary_job = 'Y';
13454 rows selected.
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1417 Card=152 Bytes=
35568)
1 0 FILTER
2 1 SORT (GROUP BY) (Cost=1417 Card=152 Bytes=35568)
3 2 HASH JOIN (Cost=254 Card=47127 Bytes=11027718)
4 3 INDEX (FAST FULL SCAN) OF 'HRM_CAREER_PK' (UNIQUE) (
Cost=12 Card=25026 Bytes=500520)
5 3 TABLE ACCESS (FULL) OF 'HRM_CAREER' (Cost=81 Card=25
335 Bytes=5421690)
Statistics
3671 recursive calls
9 db block gets
1758 consistent gets
2130 physical reads
0 redo size
2217762 bytes sent via SQL*Net to client
10359 bytes received via SQL*Net from client
898 SQL*Net roundtrips to/from client
128 sorts (memory)
1 sorts (disk)
13454 rows processed
TKPROF
TKPROF: Release 9.2.0.6.0 - Production on Wed Dec 12 18:40:56 2007
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Trace file: qnhg_ora_500.trc
Sort options: default
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
ALTER SESSION SET EVENTS '10046 trace name context forever, level 8'
call count cpu elapsed disk query current rows
Parse 0 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
total 1 0.00 0.00 0 0 0 0
Misses in library cache during parse: 0
Misses in library cache during execute: 1
Optimizer goal: CHOOSE
Parsing user id: 30 (ADMIN)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 34.45 34.45
select condition
from
cdef$ where rowid=:1
call count cpu elapsed disk query current rows
Parse 4 0.00 0.00 0 0 0 0
Execute 4 0.00 0.00 0 0 0 0
Fetch 4 0.00 0.00 0 8 0 4
total 12 0.00 0.00 0 8 0 4
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: SYS (recursive depth: 1)
Rows Row Source Operation
1 TABLE ACCESS BY USER ROWID CDEF$
select *
from hrm_career x
WHERE x.begin_date = ( SELECT MAX(begin_date)
FROM hrm_career y
WHERE y.employee_id = x.employee_id AND
begin_date <= SYSDATE AND
primary_job = 'Y') AND
x.primary_job = 'Y'
call count cpu elapsed disk query current rows
Parse 1 0.00 0.07 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 898 0.00 2.39 2038 946 9 13454
total 900 0.00 2.46 2038 946 9 13454
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 30 (ADMIN)
Rows Row Source Operation
13454 FILTER
25335 SORT GROUP BY
67496 HASH JOIN
25333 INDEX FAST FULL SCAN HRM_CAREER_PK (object id 25292)
25336 TABLE ACCESS FULL HRM_CAREER
Rows Execution Plan
0 SELECT STATEMENT GOAL: CHOOSE
13454 FILTER
25335 SORT (GROUP BY)
67496 HASH JOIN
25333 INDEX GOAL: ANALYZED (FAST FULL SCAN) OF 'HRM_CAREER_PK'
(UNIQUE)
25336 TABLE ACCESS GOAL: ANALYZED (FULL) OF 'HRM_CAREER'
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 898 0.00 0.00
SQL*Net more data to client 877 0.00 0.05
db file sequential read 1 0.01 0.01
db file scattered read 60 0.00 0.14
direct path write 9 0.00 0.00
direct path read 125 0.05 0.13
SQL*Net message from client 898 0.02 1.47
DELETE FROM PLAN_TABLE
WHERE
STATEMENT_ID=:1
call count cpu elapsed disk query current rows
Parse 2 0.00 0.00 0 0 0 0
Execute 2 0.00 0.00 0 6 6 6
Fetch 0 0.00 0.00 0 0 0 0
total 4 0.00 0.00 0 6 6 6
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 30 (ADMIN)
Rows Row Source Operation
0 DELETE
0 TABLE ACCESS FULL PLAN_TABLE
Rows Execution Plan
0 DELETE STATEMENT GOAL: CHOOSE
0 DELETE OF 'PLAN_TABLE'
0 TABLE ACCESS (FULL) OF 'PLAN_TABLE'
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 14.77 14.79
select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,
o.dataobj#,o.flags
from
obj$ o where o.obj#=:1
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 3 0 1
total 3 0.00 0.00 0 3 0 1
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: SYS (recursive depth: 1)
EXPLAIN PLAN SET STATEMENT_ID='PLUS74964' FOR select *
from hrm_career x
WHERE x.begin_date = ( SELECT MAX(begin_date)
FROM hrm_career y
WHERE y.employee_id = x.employee_id AND
begin_date <= SYSDATE AND
primary_job = 'Y') AND
x.primary_job = 'Y'
call count cpu elapsed disk query current rows
Parse 1 0.00 0.01 0 4 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
total 2 0.00 0.01 0 4 0 0
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 30 (ADMIN)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
insert into plan_table (statement_id, timestamp, operation, options,
object_node, object_owner, object_name, object_instance, object_type,
search_columns, id, parent_id, position, other,optimizer, cost, cardinality,
bytes, other_tag, partition_start, partition_stop, partition_id,
distribution, cpu_cost, io_cost, temp_space, access_predicates,
filter_predicates )
values
(:1,SYSDATE,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17,:18,:19,
:20,:21,:22,:23,:24,:25,:26,:27)
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 6 0.00 0.00 0 3 6 6
Fetch 0 0.00 0.00 0 0 0 0
total 7 0.00 0.00 0 3 6 6
Misses in library cache during parse: 1
Misses in library cache during execute: 2
Optimizer goal: CHOOSE
Parsing user id: 30 (ADMIN) (recursive depth: 1)
Rows Execution Plan
0 INSERT STATEMENT GOAL: CHOOSE
select o.name, u.name
from
sys.obj$ o, sys.user$ u where obj# = :1 and owner# = user#
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 0 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
total 1 0.00 0.00 0 0 0 0
Misses in library cache during parse: 1
Parsing user id: SYS (recursive depth: 1)
SELECT ID ID_PLUS_EXP,PARENT_ID PARENT_ID_PLUS_EXP,LPAD(' ',2*(LEVEL-1))
||OPERATION||DECODE(OTHER_TAG,NULL,'','*')||DECODE(OPTIONS,NULL,'','
('||OPTIONS||')')||DECODE(OBJECT_NAME,NULL,'',' OF '''||OBJECT_NAME||'''')
||DECODE(OBJECT_TYPE,NULL,'',' ('||OBJECT_TYPE||')')||DECODE(ID,0,
DECODE(OPTIMIZER,NULL,'',' Optimizer='||OPTIMIZER))||DECODE(COST,NULL,'','
(Cost='||COST||DECODE(CARDINALITY,NULL,'',' Card='||CARDINALITY)
||DECODE(BYTES,NULL,'',' Bytes='||BYTES)||')') PLAN_PLUS_EXP,OBJECT_NODE
OBJECT_NODE_PLUS_EXP
FROM
PLAN_TABLE START WITH ID=0 AND STATEMENT_ID=:1 CONNECT BY PRIOR ID=PARENT_ID
AND STATEMENT_ID=:1 ORDER BY ID,POSITION
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 22 0 6
total 4 0.00 0.00 0 22 0 6
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 30 (ADMIN)
Rows Row Source Operation
6 SORT ORDER BY
6 CONNECT BY WITH FILTERING
1 NESTED LOOPS
1 TABLE ACCESS FULL PLAN_TABLE
1 TABLE ACCESS BY USER ROWID PLAN_TABLE
5 NESTED LOOPS
6 BUFFER SORT
6 CONNECT BY PUMP
5 TABLE ACCESS FULL PLAN_TABLE
Rows Execution Plan
0 SELECT STATEMENT GOAL: CHOOSE
6 SORT (ORDER BY)
6 CONNECT BY (WITH FILTERING)
1 NESTED LOOPS
1 TABLE ACCESS (FULL) OF 'PLAN_TABLE'
1 TABLE ACCESS (BY USER ROWID) OF 'PLAN_TABLE'
5 NESTED LOOPS
6 BUFFER (SORT)
6 CONNECT BY PUMP
5 TABLE ACCESS (FULL) OF 'PLAN_TABLE'
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 0.09 0.09
SELECT ID ID_PLUS_EXP,OTHER_TAG OTHER_TAG_PLUS_EXP,OTHER OTHER_PLUS_EXP
FROM
PLAN_TABLE WHERE STATEMENT_ID=:1 AND OTHER_TAG IS NOT NULL ORDER BY ID
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.00 0.00 0 3 0 0
total 3 0.00 0.00 0 3 0 0
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 30 (ADMIN)
Rows Row Source Operation
0 SORT ORDER BY
0 TABLE ACCESS FULL PLAN_TABLE
Rows Execution Plan
0 SELECT STATEMENT GOAL: CHOOSE
0 SORT (ORDER BY)
0 TABLE ACCESS (FULL) OF 'PLAN_TABLE'
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 0.00 0.00
ALTER SESSION SET EVENTS '10046 trace name context off'
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
total 2 0.00 0.00 0 0 0 0
Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 30 (ADMIN)
OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
Parse 7 0.00 0.09 0 4 0 0
Execute 8 0.00 0.00 0 6 6 6
Fetch 901 0.00 2.39 2038 971 9 13460
total 916 0.00 2.49 2038 981 15 13466
Misses in library cache during parse: 6
Misses in library cache during execute: 1
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 906 0.00 0.00
SQL*Net message from client 906 34.45 50.82
SQL*Net more data to client 877 0.00 0.05
db file sequential read 1 0.01 0.01
db file scattered read 60 0.00 0.14
direct path write 9 0.00 0.00
direct path read 125 0.05 0.13
OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
Parse 7 0.00 0.00 0 0 0 0
Execute 11 0.00 0.00 0 3 6 6
Fetch 5 0.00 0.00 0 11 0 5
total 23 0.00 0.00 0 14 6 11
Misses in library cache during parse: 4
Misses in library cache during execute: 2
9 user SQL statements in session.
6 internal SQL statements in session.
15 SQL statements in session.
5 statements EXPLAINed in this session.
Trace file: qnhg_ora_500.trc
Trace file compatibility: 9.02.00
Sort options: default
3 sessions in tracefile.
12 user SQL statements in trace file.
8 internal SQL statements in trace file.
15 SQL statements in trace file.
11 unique SQL statements in trace file.
5 SQL statements EXPLAINed using schema:
ADMIN.prof$plan_table
Default table was used.
Table was created.
Table was dropped.
3945 lines in trace file.
Message was edited by:
Maran Viswarayar -
Query Uses Index in 8i but not in 9i
I have simple query which runs good in Oracle 8i. It uses index ,if i use = or in clause.
Same query is not using Index in Oracle 9i,(We made the the optimizer as choose) . If i remove in clause and make it = ,it is using index
select * from DWFE_ELE_CAT_ACC_HISTORY
where udc_acct_num in (Select z.LAH_CURR_LDC_ACCT_NUM
from DWFE_LDC_ACCT_HISTORY B,DWFE_LDC_ACCT_HISTORY z
Where B.LAH_CURR_LDC_ACCT_NUM ='0382900397'
and B.cpa_prem_num = Z.cpa_prem_num );Plan for Oracle 8i
Execution Plan
0 SELECT STATEMENT Optimizer=RULE
1 0 NESTED LOOPS
2 1 VIEW OF 'VW_NSO_1'
3 2 REMOTE* RSSCP_DB
LINK
4 1 TABLE ACCESS (BY INDEX ROWID) OF 'CAT_TRANS_HISTORY'
5 4 INDEX (RANGE SCAN) OF 'IDX3_CAT_TRANS_HISTORY' (NON-UN
IQUE)
3 SERIAL_FROM_REMOTE SELECT /*+ */ DISTINCT "A1"."LAH_CURR_LDC_AC
CT_NUM" FROM "RSSC"."LDC_ACCT_HISTOR
Statistics
0 recursive calls
0 db block gets
8 consistent gets
0 physical reads
0 redo size
7827 bytes sent via SQL*Net to client
316 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
6 rows processed
Plan for Oracle 9i
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=12018 Card=67728 Byt
es=9752832)
1 0 HASH JOIN (Cost=12018 Card=67728 Bytes=9752832)
2 1 VIEW OF 'VW_NSO_1' (Cost=707 Card=17041 Bytes=238574)
3 2 REMOTE* RSSCP_DB
LINK
4 1 TABLE ACCESS (FULL) OF 'CAT_TRANS_HISTORY' (Cost=6204 Ca
rd=1905290 Bytes=247687700)
3 SERIAL_FROM_REMOTE SELECT /*+ */ "A1"."LAH_CURR_LDC_ACCT_NUM" F
ROM "RSSC"."LDC_ACCT_HISTORY" "A2","
Statistics
42 recursive calls
1 db block gets
41038 consistent gets
41010 physical reads
380 redo size
7833 bytes sent via SQL*Net to client
253 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
6 rows processed -
Hi,
We have a production environment that uses oracle 10GR2.
We have two schemas A and B
A has two tables test1 and test2.
test1 has three columns id, name, add and has an index IDX on id1. This table has close to 500 million rows.
test2 has an column id. this is generally a small table holding 50k rows.
B has the same set of tables and indexes.
Now the question here is:
When I run a join query as
select
t1.id
from
test1 t1, test t2
where t1.id = t2.id
on schema A, the explain plan uses the index IDX
However when I run the same on schema B, the explain plan does not make use of the index.
Any Thoughts?
KarthikHere is the execution plans:
Schema A:
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| TQ |IN-OUT| PQ Distrib |
| 0 | SELECT STATEMENT | | 571 | 7423 | 37 (0)| | | |
| 1 | PX COORDINATOR | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10000 | 571 | 7423 | 37 (0)| Q1,00 | P->S | QC (RAND) |
| 3 | NESTED LOOPS | | 571 | 7423 | 37 (0)| Q1,00 | PCWP | |
| 4 | PX BLOCK ITERATOR | | | | | Q1,00 | PCWC | |
| 5 | TABLE ACCESS FULL| TEST2 | 153 | 918 | 6 (0)| Q1,00 | PCWP | |
|* 6 | INDEX RANGE SCAN | IDX | 4 | 28 | 0 (0)| Q1,00 | PCWP | |
Predicate Information (identified by operation id):
access("TEST1"."ID"="TEST2"."ID")
Schema B:
Plan hash value: 2574051690
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
| 0 | SELECT STATEMENT | | 3108K| 38M| 5581 (3)| 00:01:07 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | 3108K| 38M| 5581 (3)| 00:01:07 | Q1,01 | P->S | QC (RAND) |
|* 3 | HASH JOIN | | 3108K| 38M| 5581 (3)| 00:01:07 | Q1,01 | PCWP | |
| 4 | PX RECEIVE | | 196K| 1149K| 50 (4)| 00:00:01 | Q1,01 | PCWP | |
| 5 | PX SEND BROADCAST | :TQ10000 | 196K| 1149K| 50 (4)| 00:00:01 | Q1,00 | P->P | BROADCAST |
| 6 | PX BLOCK ITERATOR | | 196K| 1149K| 50 (4)| 00:00:01 | Q1,00 | PCWC | |
| 7 | TABLE ACCESS FULL | TEST2 | 196K| 1149K| 50 (4)| 00:00:01 | Q1,00 | PCWP | |
| 8 | PX BLOCK ITERATOR | | 121M| 809M| 5472 (2)| 00:01:06 | Q1,01 | PCWC | |
| 9 | INDEX FAST FULL SCAN| IDX | 121M| 809M| 5472 (2)| 00:01:06 | Q1,01 | PCWP | |
Predicate Information (identified by operation id):
access("TEST1"."ID"="TEST2"."ID") -
What is mean by index range scan and fast full scan
What is mean by the following execution plans
1)Table access by index rowid
2) Index range scan
3) Index fast full scan
4) global index by rowid
..etc
where i can get this information.In what situation CBO take these paths.Can you pls give me a link where i can find all these.I read these long time ago but not able to recollect
Thanks
AnandOracle® Database Performance Tuning Guide
10g Release 2 (10.2)
Part Number B14211-01
13.5 Understanding Access Paths for the Query Optimizer
http://download-east.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#sthref1281 -
How to use indexes correctly in oracle
Hi guys
on one table i have indexes on 3 columns in the following order
a
b
c
When i m writing a select statement in my where clause what should be the order? like
where
a='some value' and
b='some value' and
c='some value';
or in reverse order like this
c='some value' and
b='some value' and
a='some value';
please let me know.
ThanksIf you have an index on a,b,c the difference in performance can be on the index order.
If column "a" has only 2 unique values then the sub values of the index only has 50% of the remaining values, the cost optimizer on Oracle will probably skip the index as an index scan of 50% is slower than a full table scan.
If a has 100 unique values then the remaining search is only on 1% of the values so is likely to be used.
As with any optimisation try using
explain plan for selec x,y,z from a_table
from where
a='some value' and
b='some value' and
c='some value'
If the index is not being used firstly try
analyze table estimate statistics
sample 10 percent
for all indexes
for all indexed columns;
and failing than try different orders in acceptance environment.
Maybe you are looking for
-
I installed Mountain Lion on my 2010 Macbook Pro without incident on launch day. I had to then go away for the rest of the week and weekend. Yesturday and today, randomly everything seems to freeze, the video looks like it scrambles and I have to har
-
DB link between Oracle 9i and MS SQL server2000
Hi, Is it possible to create a DB link between Oracle 9i and MS SQL server 2000. If it is possible what are the different ways of creating it. Is it possible without purchasing any propietery drivers. Thanks, Rohit
-
MOVED: how to use the karaoke function in realtek soundmanager
This topic has been moved to Off-Topic Technical. https://forum-en.msi.com/index.php?topic=102163.0
-
Connecting to multi databases from Oracle Forms
I am trying to connect to 2 databases from my form. The primary connection is to a datbase where reports information(i.e. Report name,parameters) is saved. When the form runs and user picks a report to run, i want to change connection to a different
-
How we will update data in datasources
hi gurus, how we will update data in data sources say salesorder header data, delivery&billing data and how can we link all these. i think my question is not correct, but i am gettin doubt please clear anybody it will helpful for me thanks in advanc