频繁的表table access full sacn

[复制链接]
查看11 | 回复7 | 2010-1-4 08:33:08 | 显示全部楼层 |阅读模式
服务器: AIX5.2
数据库: oracle9.2.0.8
现状描述:
查看视图v$session_longops发现有一个对表order_head(2000万记录)的全表扫描操作非常频繁。但是利用v$session_longops视图提供的hahs_value值到v$sqltext和v$sql_plan中又找不到对应的记录,最后使用了一种笨方法(不停地执行对上述两个表的查询),终于获得到对应语句和实际的执行计划。
SQL语句:
Select fieldlist
from order_head
where order_date = :2
and order_status:3
and order_status:4
执行计划:
SELECT STATEMENT, GOAL = CHOOSE

TABLE ACCESS FULL
对象名称=ORDER_HEADER

索引
存在order_date上的单键索引

问题描述
1,
为什么这条语句在v$sql和v$sql_plan中不太容易找到(需要很耐心的不停刷新这两个视图才找得到)?
2,
为什么这条语句在pl/developer中执行的时候走了索引而实际没走索引?
3,
怎么解决这个问题?
回复

使用道具 举报

千问 | 2010-1-4 08:33:08 | 显示全部楼层
pl/developer很多时候不准.
回复

使用道具 举报

千问 | 2010-1-4 08:33:08 | 显示全部楼层
如果你表上列很多的话.
我觉得你可以在fieldlist ,order_date,order_status建联合索引.
然后把句子改成:
Select /*+ index_ffs(order_head indexname) */fieldlist
from order_head
where order_date = :2
and order_status:3
and order_status:4
不妨试一下.
回复

使用道具 举报

千问 | 2010-1-4 08:33:08 | 显示全部楼层
嗯,Orain说得不错,如果执行计划确实不太好的话,你可以通过添加Hint来指定索引,这样就会使执行计划变得好看些。
但是需要强调的,Hint不是万能的,如果察看Oracle ERP后台的存储过程,你会发现这个用得很少。
回复

使用道具 举报

千问 | 2010-1-4 08:33:08 | 显示全部楼层
1,我用命令窗口登陆到sqlplus中执行,一样是可以使用索引的;
2,使用hint是可以解决问题,单这个语句是用前面的java组件拼凑出来的;不太容易修改。
回复

使用道具 举报

千问 | 2010-1-4 08:33:08 | 显示全部楼层
》1,为什么这条语句在v$sql和v$sql_plan中不太容易找到(需要很耐心的不停刷新这两个视图才找得到)?
应该可以早到的。
2,为什么这条语句在pl/developer中执行的时候走了索引而实际没走索引?
也许是peeking的问题,或许你的日期查询范围很大。
》3,怎么解决这个问题?
order_head(2000万记录)这么大,查询v$sql 的buffer get/exec 一定很高。
查询
回复

使用道具 举报

千问 | 2010-1-4 08:33:08 | 显示全部楼层


正确的建索引、定期的收集统计信息才是正道~原帖由 justinzang 于 2009-1-22 10:14 发表
嗯,Orain说得不错,如果执行计划确实不太好的话,你可以通过添加Hint来指定索引,这样就会使执行计划变得好看些。
但是需要强调的,Hint不是万能的,如果察看Oracle ERP后台的存储过程,你会发现这个用得很少。

回复

使用道具 举报

千问 | 2010-1-4 08:33:08 | 显示全部楼层
问题解决了
原因有点抓狂。
前台程序员在传参数的时候莫名其妙将日期参数转换为了timestamp类型,造成oracle执行过程中的隐式转换。
简单测试如下。
select * from order_header oh
where oh.order_date between trunc(sysdate) and sysdate
―――――――――――――――――
SELECT STATEMENT, GOAL = CHOOSE

TABLE ACCESS BY INDEX ROWID 对象名称=ORDER_HEADER

INDEX RANGE SCAN对象名称=ORDER_HDR_DATE

――――――――――
select * from order_header oh
where oh.order_date between CAST(trunc(sysdate) AS TIMESTAMP)
and CAST(sysdate AS TIMESTAMP)
――――――――――――――――
SELECT STATEMENT, GOAL = CHOOSE

TABLE ACCESS FULL 对象名称=ORDER_HEADER


----------------------------------------------
我。。。。。。。。。。。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行