- UID
- 12521
- 阅读权限
- 100
- 帖子
- 14333
- 精华贴数
- 57
- 技术排名
- 23
- 技术积分
- 51713
- 社区排名
- 591
- 社区积分
- 3825
- 注册时间
- 2002-5-26
- 精华贴数
- 57
- 技术积分
- 51713
- 社区积分
- 3825
- 注册时间
- 2002-5-26
- 论坛徽章:
- 76
|
今天,现场人员报告说,历史查询服务器很慢,一样的SQL放到主库中运行比转发到历史查询库上要快很多。
于是要来SQL,在两个库中分别查看执行计划。
select /*+rule*/ cola,colb
from tablea
where colc in (....)
and cold >= 111 and cold <=222;
主库中是使用了cold上的索引,而历史库中则使用了全表扫描,这是导致查询速度差异的原因。
但是问题是,仔细检查了两个库中的表,所有的列定义,索引定义,分区定义都是一样的,而且由于SQL中明确指定了/*+RULE*/的提示,所以也排除了数据在两个库中分布不一样的问题。
cold是表的PK中的第一个字段。
以下所有的操作都是在历史库中进行的:
1。去除了/*+RULE*/提示,改用FIRST_ROWS,执行计划没有变化,仍然使用了全表扫描,改为/*+use_index(table,index)*/,仍然全表扫描。
2。作了一次25%的estimate,使用FIRST_ROWS,执行计划改变为使用正确的索引了。但是/*+RULE*/和/*+use_index(table,index)*/仍然全表扫描
3。作100053的trace,奇怪的问题出现了,居然udump目录中不生成任何trace文件。
alter session set events '10053 trace name context forever, level 1';
explain plan for ...
alter session set events '10053 trace name context off';
4。于是禁用主键,同时删除了index,然后重新启用主键,此时unique index自动创建了。再次查看执行计划,全部正常了。
5。用dbms_stats包gather_table_stats,重新执行SQL,发现又再次变为全表扫描
6。用dbms_stats包delete_table_stats之后重新开始使用索引。
至此基本上明白是统计信息的收集导致了在使用/*+RULE*/时,SQL没有正确地遵守RBO的规则。
奇怪的问题。
100053没有trace生成也是奇怪的问题。
数据库 是8174
optimizer_mode设置为first_rows |
|