在程序中使用带参数的函数访问oracle 数据库,查看执行计划发现做了全表扫描。但是如果我使用拼接字符串的方式在程序中访问,或者直接在sqlplus中执行,查看其执行计划确实走了索引。
这是怎么回事?.net程序访问oracle数据库中的表T2,其中RT字段为timestamp类型,建立normal索引。
代码中使用了带参数的sql语句:
select C1 , C2 , C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 ,
C11 , C12 , C13 , C14 , C15 , C16 , C17 , C18 , C19 ,
C20 , RT from ( select /*+index(T2 ,RT )*/C1 , C2 ,
C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 , C11 , C12 ,
C13 , C14 , C15 , C16 , C17 , C18 , C19 , C20 , RT
from T6 where RT>:lastTime order by RT desc ) where rownum<=:maxRow
发现执行时间非常长,大约4分钟。
在v$sql_plan中
是用了全表扫描,然后排序。
但我在sqlplus中直接执行拼接的sql语句,就会走索引,很快返回结果。
select C1 , C2 , C3 , C4 , C5 , C6 ,
C7 , C8 , C9 , C10 , C11 , C12 , C13 , C14 , C15 ,
C16 , C17 , C18 , C19 , C20 ,
RT from ( select C1 , C2 , C3 , C4 , C5 , C6 , C7 ,
C8 , C9 , C10 , C11 , C12 , C13 , C14 ,
C15 , C16 , C17 , C18 , C19 , C20 , RT from test.T2
where RT>to_date('2012-10-16','yyyy-mm-dd') order by RT desc ) where rownum<= 100
这时什么原因造成的,带参数的sql为什么用了hint也没办法强制oracle走索引。
analyze表之后,带参数的sql也走索引了。但我发现一天以后这个毛病就又返了,难道需要管理员每天analyze一下这个表吗?
有什么办法能在程序层面解决这个问题,我的目的是希望能做到尽量不用系统管理员干预就能取得稳定的性能。
这是怎么回事?.net程序访问oracle数据库中的表T2,其中RT字段为timestamp类型,建立normal索引。
代码中使用了带参数的sql语句:
select C1 , C2 , C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 ,
C11 , C12 , C13 , C14 , C15 , C16 , C17 , C18 , C19 ,
C20 , RT from ( select /*+index(T2 ,RT )*/C1 , C2 ,
C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 , C11 , C12 ,
C13 , C14 , C15 , C16 , C17 , C18 , C19 , C20 , RT
from T6 where RT>:lastTime order by RT desc ) where rownum<=:maxRow
发现执行时间非常长,大约4分钟。
在v$sql_plan中
是用了全表扫描,然后排序。
但我在sqlplus中直接执行拼接的sql语句,就会走索引,很快返回结果。
select C1 , C2 , C3 , C4 , C5 , C6 ,
C7 , C8 , C9 , C10 , C11 , C12 , C13 , C14 , C15 ,
C16 , C17 , C18 , C19 , C20 ,
RT from ( select C1 , C2 , C3 , C4 , C5 , C6 , C7 ,
C8 , C9 , C10 , C11 , C12 , C13 , C14 ,
C15 , C16 , C17 , C18 , C19 , C20 , RT from test.T2
where RT>to_date('2012-10-16','yyyy-mm-dd') order by RT desc ) where rownum<= 100
这时什么原因造成的,带参数的sql为什么用了hint也没办法强制oracle走索引。
analyze表之后,带参数的sql也走索引了。但我发现一天以后这个毛病就又返了,难道需要管理员每天analyze一下这个表吗?
有什么办法能在程序层面解决这个问题,我的目的是希望能做到尽量不用系统管理员干预就能取得稳定的性能。
才是index hint的用法。
但是不用hint为什么就走索引呢。
******************************************
Current SQL statement for this session:
select C1 , C2 , C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 , C11 , C12 , C13 , C14 , C15 , C16 , C17 , C18 , C19 , C20 , RT from ( select C1 , C2 , C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 , C11 , C12 , C13 , C14 , C15 , C16 , C17 , C18 , C19 , C20 , RT from T6 where RT>:lastTime order by RT desc ) where rownum<=:maxRow
***************************************
BASE STATISTICAL INFORMATION
***********************
Table Stats::
Table: T6 Alias: T6
#Rows: 671932 #Blks: 10733 AvgRowLen: 111.00
Index Stats::
Index: INDEX_T6_RT Col#: 21
LVLS: 2 #LB: 1768 #DK: 670274 LB/K: 1.00 DB/K: 1.00 CLUF: 542441.00
***************************************
SINGLE TABLE ACCESS PATH
Column (#21): RT(TIMESTAMP)
AvgLen: 11.00 NDV: 671932 Nulls: 0 Density: 1.4882e-006 Min: 2456165 Max: 2456220
Histogram: HtBal #Bkts: 254 UncompBkts: 254 EndPtVals: 255
Table: T6 Alias: T6
Card: Original: 671932 Rounded: 33597 Computed: 33596.60 Non Adjusted: 33596.60
Access Path: TableScan
Cost: 2432.41 Resp: 2432.41 Degree: 0
Cost_io: 2350.00 Cost_cpu: 479593616
Resp_io: 2350.00 Resp_cpu: 479593616
Access Path: index (RangeScan)
Index: INDEX_T6_RT
resc_io: 4913.00 resc_cpu: 39523635
ix_sel: 0.0090223 ix_sel_with_filters: 0.0090223
Cost: 4919.79 Resp: 4919.79 Degree: 1
Best:: AccessPath: TableScan
Cost: 2432.41 Degree: 1 Resp: 2432.41 Card: 33596.60 Bytes: 0
***************************************
OPTIMIZER STATISTICS AND COMPUTATIONS
***************************************
GENERAL PLANS
***************************************
Considering cardinality-based initial join order.
***********************
Join order[1]: T6[T6]#0
ORDER BY sort
SORT resource Sort statistics
Sort width: 227 Area size: 199680 Max Area size: 40054784
Degree: 1
Blocks to Sort: 548 Row size: 133 Total Rows: 33597
Initial runs: 2 Merge passes: 1 IO Cost / pass: 298
Total IO sort cost: 846 Total CPU sort cost: 42074783
Total Temp space used: 10806000
***********************
Best so far: Table#: 0 cost: 3285.6384 card: 33596.6000 bytes: 3729267
*********************************
Number of join permutations tried: 1
*********************************
SORT resource Sort statistics
Sort width: 227 Area size: 199680 Max Area size: 40054784
Degree: 1
Blocks to Sort: 548 Row size: 133 Total Rows: 33597
Initial runs: 2 Merge passes: 1 IO Cost / pass: 298
Total IO sort cost: 846 Total CPU sort cost: 42074783
Total Temp space used: 10806000
Final - All Rows Plan: Best join order: 1
Cost: 3285.6384 Degree: 1 Card: 33597.0000 Bytes: 3729267
Resc: 3285.6384 Resc_io: 3196.0000 Resc_cpu: 521668398
Resp: 3285.6384 Resp_io: 3196.0000 Resc_cpu: 521668398
kkoipt: Query block SEL$2 (#0)
******* UNPARSED QUERY IS *******
SELECT /*+ NO_STAR_TRANSFORMATION NO_EXPAND */ "T6"."C1" "C1","T6"."C2" "C2","T6"."C3" "C3","T6"."C4" "C4","T6"."C5" "C5","T6"."C6" "C6","T6"."C7" "C7","T6"."C8" "C8","T6"."C9" "C9","T6"."C10" "C10","T6"."C11" "C11","T6"."C12" "C12","T6"."C13" "C13","T6"."C14" "C14","T6"."C15" "C15","T6"."C16" "C16","T6"."C17" "C17","T6"."C18" "C18","T6"."C19" "C19","T6"."C20" "C20","T6"."RT" "RT" FROM "TEST"."T6" "T6" WHERE "T6"."RT">:B1 ORDER BY "T6"."RT" DESC
kkoqbc-end
: call(in-use=57448, alloc=0), compile(in-use=54392, alloc=0)
kkoqbc-start
: call(in-use=56080, alloc=0), compile(in-use=56468, alloc=0)
****************
QUERY BLOCK TEXT
****************
select C1 , C2 , C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 , C11 , C12 , C13 , C14 , C15 , C16 , C17 , C18 , C19 , C20 , RT from ( select C1 , C2 , C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 , C11 , C12 , C13 , C14 , C15 , C16 , C17 , C18 , C19 , C20 , RT from T6 where RT>:lastTime order by RT desc ) where rownum<=:maxRow
============
Plan Table
============
-------------------------------------------+-----------------------------------+
| Id | Operation | Name | Rows | Bytes | Cost | Time |
-------------------------------------------+-----------------------------------+
| 0 | SELECT STATEMENT | | | | 3286 | |
| 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 33K | 8301K | 3286 | 00:00:40 |
| 3 | SORT ORDER BY STOPKEY | | 33K | 3642K | 3286 | 00:00:40 |
| 4 | TABLE ACCESS FULL | T6 | 33K | 3642K | 2432 | 00:00:30 |
-------------------------------------------+-----------------------------------+
select C1 , C2 , C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 , C11 , C12 , C13 , C14 , C15 , C16 , C17 , C18 , C19 , C20 , RT
from ( select C1 , C2 , C3 , C4 , C5 , C6 , C7 , C8 , C9 , C10 , C11 , C12 , C13 , C14 , C15 , C16 , C17 , C18 , C19 , C20 , RT
from test.T1 where RT>to_date('2012-10-19','yyyy-mm-dd') order by RT desc ) where rownum<=100trace上面这条语句 发现他走索引cost居然只有4。这又是为什么啊。***************************************
SINGLE TABLE ACCESS PATH
Column (#21): RT(TIMESTAMP)
AvgLen: 11.00 NDV: 671747 Nulls: 0 Density: 1.4887e-006 Min: 2456165 Max: 2456220
Histogram: HtBal #Bkts: 254 UncompBkts: 254 EndPtVals: 255
Using prorated density: 1.4884e-006 of col #21 as selectivity of out-of-range value pred
Table: T1 Alias: T1
Card: Original: 671747 Rounded: 1 Computed: 1.00 Non Adjusted: 1.00
Access Path: TableScan
Cost: 2404.23 Resp: 2404.23 Degree: 0
Cost_io: 2322.00 Cost_cpu: 478571071
Resp_io: 2322.00 Resp_cpu: 478571071
Using prorated density: 1.4884e-006 of col #21 as selectivity of out-of-range value pred
Access Path: index (RangeScan)
Index: INDEX_T1_RT
resc_io: 4.00 resc_cpu: 29236
ix_sel: 1.4906e-006 ix_sel_with_filters: 1.4906e-006
Cost: 4.01 Resp: 4.01 Degree: 1
Best:: AccessPath: IndexRange Index: INDEX_T1_RT
Cost: 4.01 Degree: 1 Resp: 4.01 Card: 1.00 Bytes: 0