Oracle执行计划分析及实际生产案例解析

本文介绍了Oracle数据库中SQL查询的优化基础,包括Where条件的执行顺序,强调表连接应置于其他条件之前,重要条件放最后。通过查看执行计划(使用F5或F8)来分析SQL效率,关注ID、Operation、基数、Bytes、COST和Time等关键列。以一个分区表查询案例说明,当分区字段不明确时,查询无法有效利用分区,调整为明确条件后能提高查询性能。
摘要由CSDN通过智能技术生成

一、SQL优化基础

1.Oracle数据库Where条件执行顺序:自下而上。

由于SQL优化起来比较复杂,并且还会受环境限制,ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。

 

二、查看执行计划

在SQL语句上,按F5,查看Oracle语句执行计划

或者:F8执行语句

 explain plan for select COUNT(*)  from taba A,tabb B where   a.CITY =591 and B.CITY=591;
 select * from table(dbms_xplan.display());


执行计划的常用列字段解释:
ID:个序号,但不是执行的先后顺序。执行的先后根据缩进来判断。
Operation: 当前操作的内容。
基数(Rows):Oracle估计的当前操作的返回结果集行数
字节(Bytes):执行该步骤后返回的字节数
耗费(COST)、CPU耗费:Oracle估计的该步骤的执行成本,用于说明SQL执行的代价,理论上越小越好(该值可能与实际有出入)
时间(Time):Oracle估计的当前操作所需的时间

 

执行顺序:先执行缩进多的(层次深的),如果层次相同,就从上往下执行。

三、案例解析

1.分区字段不明确,导致用不上分区,生产查询需要100s,优化后变成1s

drop table users;
create table users(
  user_id VARCHAR2(15),
  home_city number(3),
  user_name VARCHAR2(50),
  remark     VARCHAR2(100),
  create_time date
);
create index idx1_users on users(user_id);
create table balance(
);
drop table pay_record;
create table pay_record(
  pay_id VARCHAR2(15),
  home_city number(3),
  out_user_id number(15),
  in_user_id number(15),
  amount number(10),
  status number(1),
  pay_time date,
  create_time date
)
partition by range(home_city,pay_time) 
(
partition pay_time_20210411 values less than (591,to_date('20210411','yyyyMMdd')),
partition pay_time_20210412 values less than (591,to_date('20210412','yyyyMMdd')),
partition pay_time_20210413 values less than (591,to_date('20210413','yyyyMMdd')),
partition pay_time_20210414 values less than (591,to_date('20210414','yyyyMMdd')),
partition pay_time_20210415 values less than (591,to_date('20210415','yyyyMMdd')),
partition pay_time_59220210411 values less than (592,to_date('20210411','yyyyMMdd')),
partition pay_time_59220210412 values less than (592,to_date('20210412','yyyyMMdd')),
partition pay_time_59220210413 values less than (592,to_date('20210413','yyyyMMdd')),
partition pay_time_59220210414 values less than (592,to_date('20210414','yyyyMMdd')),
partition pay_time_59220210415 values less than (592,to_date('20210415','yyyyMMdd'))
);

users :索引user_id

pay_record:  分区home_city,pay_time

explain plan for select * from  users a,pay_record b  
where
   a.home_city=b.home_city;
select * from table(dbms_xplan.display());

这样的结果是 b表用不上分区,因为home_city不是确定的,无法落到具体的分区上。

此时查询执行计划,发现:

PARTITION RANGE ALL    相当于全表扫描

改成  a.home_city=:xxx  and b.home_city=:xxx

PARTITION RANGE ITERATOR   用上分区了

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值