oracle下一条SQL语句的优化过程(比较详细)
XSTFXPS1_PK DHAO00
211 bytes sent via SQL*Net to client
and trunc(sysdate)+1-1/(24*60*60);
XKZH00 VARCHAR2(12)
where a.dhao00=b.dhao00;
275 bytes received via SQL*Net from client
SPDM00 VARCHAR2(8)
SE0000 NUMBER Y
0 sorts (disk)
INDEX_NAME COLUMN_NAME
and b.ywrq00 between trunc(sysdate)
832 redo size
COUNT(*)
Statistics
select sum(sl0000) from xstfxps2 where
SHBJ00 VARCHAR2(1) 'N'
3 consistent gets
----------------------------------------------------------
5 4 INDEX (UNIQUE SCAN) OF 'XSTFXPS1_PK' (UNIQUE)
FXBJ00 VARCHAR2(1) 'N'
2 1 NESTED LOOPS
原来的语句是这样的:
Name Type Nullable Default Comments
XSTFXPS2_PK DHAO00
Execution Plan
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'XSTFXPS2'
0 sorts (memory)
调整的第一步是把子查询提取出来,再看语句的执行计划。通常来说,如果语句能够避免子查询的使用,就尽量不用子查询。因为子查询的开销是相当昂贵的。改写后的语句如下:
5 4 INDEX (RANGE SCAN) OF 'IDX_XSTFXPS1_KHDM00_YWRQ00'
2 SQL*Net roundtrips to/from client
YWRQ00 DATE Y
0 sorts (memory)
0 physical reads
----------
5 3 INDEX (RANGE SCAN) OF 'XSTFXPS2_PK' (UNIQUE)
and khdm00='500000003913') b
2 SQL*Net roundtrips to/from client
0 recursive calls
1 0 SORT (AGGREGATE)
3 2 TABLE ACCESS (FULL) OF 'XSTFXPS2'
------------------------------ -----------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
SQL> select count(*) from xstfxps2;
DHAO00 NUMBER(8)
FXRYDM VARCHAR2(4) Y
我们这里看到XSTFXPS2这张表有5585018条记录。
create index idx_xstfxps1_khdm00_ywrq00 on xstfxps1(khdm00,ywrq00) tablespace indx;
where a.dhao00=b.dhao00
COUNT(*)
LHDH00 NUMBER(8) Y
为了使用索引,我们必须对原来的日期字段的条件进行一些调整。因为有个trunc()函数的存在,语句将不会使用到索引。我们只要明白trunc(ywrq00)=trunc(sysdate)事实上等同于ywrq00大于trunc(sysdate),小于trunc(sysdate+1)减去一秒,我们就有了比较好的办法来处理
FPHAO0 VARCHAR2(10) Y
select index_name,column_name from dba_ind_columns where table_name like 'XSTFXPS%'
------ ------------ -------- ------- --------
0 SELECT STATEMENT Optimizer=CHOOSE
6 3 INDEX (RANGE SCAN) OF 'XSTFXPS2_PK' (UNIQUE)
FPBBH0 VARCHAR2(11) Y
已用时间: 00: 00: 03.05
1 rows processed
0 db block gets
FXSL00 NUMBER Y 0
0 db block gets
Execution Plan
----------------------------------------------------------
1 rows processed
2 SQL*Net roundtrips to/from client
FKDM00 VARCHAR2(2) Y
2912 redo size
225 physical reads
and b.khdm00='500000003913'
4 3 TABLE ACCESS (BY INDEX ROWID) OF 'XSTFXPS1'
----------
JE0000 NUMBER Y 0
SQL> select count(*) from xstfxps1;
已用时间: 00: 02: 49.04
1 0 SORT (AGGREGATE)
11974 consistent gets
Statistics
THSL00 NUMBER Y 0
----------------------------------------------------------
----------------------------------------------------------
dhao00 in (
(NON-UNIQUE)
4 2 TABLE ACCESS (BY INDEX ROWID) OF 'XSTFXPS1'
RBDH00 NUMBER(8) Y
SQL> desc xstfxps2
Statistics
SHRYDM VARCHAR2(4) Y
0 recursive calls
XSFSDM VARCHAR2(2) Y
17355138 consistent gets
198 bytes sent via SQL*Net to client
3 2 NESTED LOOPS
3 2 NESTED LOOPS
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'XSTFXPS2'
------ ------------ -------- ------- --------
FPLB00 VARCHAR2(2) Y
SL0000 NUMBER Y 0
0 sorts (disk)
275 bytes received via SQL*Net from client
0 sorts (memory)
DHAO00 NUMBER(8)
702121
1 0 SORT (AGGREGATE)
0 recursive calls
我们可以看到逻辑IO由原来的17355138次下降到11974次,有了数量级的提升。执行时间也有原来将近3分钟下降到现在的3秒多一些。很显然性能有了大幅的提升。不过我们看到执行计划里面表XSTFXPS1还是有一个全表扫描存在。通常来说我们应该尽量避免全表扫描的存在,尤其对于大表,应该建立合适的索引以避免FTS的产生。我们来看这两张表的索引信息:
我们看到统计信息里面进行了17355138次逻辑读,34141次物理IO,这是相当吓人的数字。在执行计划里面我们看到表XSTFXPS2来了一次全表扫描。
0 db block gets
DJIA00 NUMBER(7,2) 0
from xstfxps2 a, xstfxps1 b
275 bytes received via SQL*Net from client
我们首先看一下这两张表总的数据量:
KHDM00 VARCHAR2(12)
Name Type Nullable Default Comments
0 sorts (disk)
SKBJ00 VARCHAR2(2) Y
select sum(sl0000)
XSQRRQ DATE Y
select sum(sl0000)
34141 physical reads
两张表的表结构如下所示:
5585018
XSQRRY VARCHAR2(8) Y
THCKDM VARCHAR2(2) Y
Execution Plan
select dhao00 from xstfxps1 where trunc(ywrq00)=trunc(sysdate)
----------------------------------------------------------
210 bytes sent via SQL*Net to client
0 SELECT STATEMENT Optimizer=CHOOSE
1 rows processed
其中XSTFXPS1的客户订单的表头,保存订单的客户信息、订货日期等信息。XSTFXPS2是订单的表体,详细记录了客户订单的商品、价格、数量等信息。
CKDM00 VARCHAR2(2) Y
我们看到这两张表除了主键约束外都没有建另外的索引。根据语句的查询情况,我们建立了如下的复合索引:
4 3 TABLE ACCESS (FULL) OF 'XSTFXPS1'
YWRY00 VARCHAR2(8) Y
XSTFXPS2_PK SPDM00
SQL> desc xstfxps1
SHRQ00 DATE Y
0 redo size
FLDH00 NUMBER(8) Y
and khdm00='500000003913');
----------------------------------------------------------
我们这时候看逻辑IO已经降为3次,语句的执行计划也符合我们的调整目标,创建的索引产生了比较大的效果。这条语句的调整至此告一段落。 这个条件。最终改写后的语句如下:
from xstfxps2 a,(select dhao00 from xstfxps1 where trunc(ywrq00)=trunc(sysdate)
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://www.juheyunku.com/sql/oracle/3253.shtml
相关文章
热门TAG
命令 权重 外链 企业网站 白帽 php 织梦教程 dedecms修改内容 javascript 织梦 功能 标签 调用 详解 服务器 网站流量 实例解析 Dedecms 织梦cms HTML tags标签 python jquery教程 jquery windows SEO优化 蜘蛛 搜索引擎 网站收录 JSP最新文章
-
Window下Oracle Database 11g 发行
时间:2020-12-29
-
Oracle如何实现like多个值的
时间:2020-12-29
-
maven添加oracle依赖失败问题
时间:2020-12-29
-
OracleRAC基本概念及入门
时间:2020-12-29
-
Azure File Storage 基本用法
时间:2020-12-26
-
Oracle 权限(grant revoke)
时间:2020-12-26
-
Azure Queue Storage 基本用法
时间:2020-12-26
-
如何对比迁移前后的Orac
时间:2020-12-26
热门文章
-
Azure Queue Storage 基本用法 Azure Storage 之
时间:2020-12-26
-
Oracle存储过程编程详解
时间:2020-12-07
-
win10下oracle 11g安装图文教程
时间:2020-12-25
-
oracle 数据库学习 基本结构介绍
时间:2020-12-13
-
Azure File Storage 基本用法 Azure Storage 之 F
时间:2020-12-26
-
windows使用sqlpus连接oracle 数据库的教程图
时间:2020-12-25
-
Window下Oracle Database 11g 发行版2安装教程
时间:2020-12-29
-
Oracle解锁的方式介绍
时间:2020-12-14
-
linux下oracle设置开机自启动实现方法
时间:2020-12-13
-
Oracle学习记录之使用自定义函数和触发器
时间:2020-12-07
