oracle下一条SQL语句的优化过程(比较详细)

更新时间:2010年04月14日 23:56:49   作者:

很简单的一次调整,语句加了适当的索引后性能就有大幅的提升。当时看到这条语句的时候,第一感觉就是执行效率肯定低下。语句的功能是求某一客户当天产品的总销量。

原来的语句是这样的:

select sum(sl0000) from xstfxps2 where

dhao00 in (

select dhao00 from xstfxps1 where trunc(ywrq00)=trunc(sysdate)

and khdm00='500000003913');

已用时间: 00: 02: 49.04

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 SORT (AGGREGATE)

2 1 NESTED LOOPS

3 2 TABLE ACCESS (FULL) OF 'XSTFXPS2'

4 2 TABLE ACCESS (BY INDEX ROWID) OF 'XSTFXPS1'

5 4 INDEX (UNIQUE SCAN) OF 'XSTFXPS1_PK' (UNIQUE)

Statistics

----------------------------------------------------------

0 recursive calls

0 db block gets

17355138 consistent gets

34141 physical reads

2912 redo size

198 bytes sent via SQL*Net to client

275 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1 rows processed

我们看到统计信息里面进行了17355138次逻辑读,34141次物理IO,这是相当吓人的数字。在执行计划里面我们看到表XSTFXPS2来了一次全表扫描。

我们首先看一下这两张表总的数据量:

SQL> select count(*) from xstfxps2;

COUNT(*)

----------

5585018

我们这里看到XSTFXPS2这张表有5585018条记录。

SQL> select count(*) from xstfxps1;

COUNT(*)

----------

702121

两张表的表结构如下所示:

SQL> desc xstfxps1

Name Type Nullable Default Comments

------ ------------ -------- ------- --------

DHAO00 NUMBER(8)

LHDH00 NUMBER(8) Y

FLDH00 NUMBER(8) Y

FPLB00 VARCHAR2(2) Y

YWRQ00 DATE Y

YWRY00 VARCHAR2(8) Y

SHRQ00 DATE Y

XSQRRQ DATE Y

XSQRRY VARCHAR2(8) Y

KHDM00 VARCHAR2(12)

XKZH00 VARCHAR2(12)

CKDM00 VARCHAR2(2) Y

THCKDM VARCHAR2(2) Y

XSFSDM VARCHAR2(2) Y

FXRYDM VARCHAR2(4) Y

SHRYDM VARCHAR2(4) Y

SHBJ00 VARCHAR2(1) 'N'

FXBJ00 VARCHAR2(1) 'N'

SKBJ00 VARCHAR2(2) Y

FKDM00 VARCHAR2(2) Y

SQL> desc xstfxps2

Name Type Nullable Default Comments

------ ------------ -------- ------- --------

DHAO00 NUMBER(8)

SPDM00 VARCHAR2(8)

DJIA00 NUMBER(7,2) 0

FXSL00 NUMBER Y 0

SL0000 NUMBER Y 0

THSL00 NUMBER Y 0

JE0000 NUMBER Y 0

SE0000 NUMBER Y

FPBBH0 VARCHAR2(11) Y

FPHAO0 VARCHAR2(10) Y

RBDH00 NUMBER(8) Y

其中XSTFXPS1的客户订单的表头,保存订单的客户信息、订货日期等信息。XSTFXPS2是订单的表体,详细记录了客户订单的商品、价格、数量等信息。

调整的第一步是把子查询提取出来,再看语句的执行计划。通常来说,如果语句能够避免子查询的使用,就尽量不用子查询。因为子查询的开销是相当昂贵的。改写后的语句如下:

select sum(sl0000)

from xstfxps2 a,(select dhao00 from xstfxps1 where trunc(ywrq00)=trunc(sysdate)

and khdm00='500000003913') b

where a.dhao00=b.dhao00;

已用时间: 00: 00: 03.05

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 SORT (AGGREGATE)

2 1 TABLE ACCESS (BY INDEX ROWID) OF 'XSTFXPS2'

3 2 NESTED LOOPS

4 3 TABLE ACCESS (FULL) OF 'XSTFXPS1'

5 3 INDEX (RANGE SCAN) OF 'XSTFXPS2_PK' (UNIQUE)

Statistics

----------------------------------------------------------

0 recursive calls

0 db block gets

11974 consistent gets

225 physical reads

832 redo size

211 bytes sent via SQL*Net to client

275 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1 rows processed

我们可以看到逻辑IO由原来的17355138次下降到11974次,有了数量级的提升。执行时间也有原来将近3分钟下降到现在的3秒多一些。很显然性能有了大幅的提升。不过我们看到执行计划里面表XSTFXPS1还是有一个全表扫描存在。通常来说我们应该尽量避免全表扫描的存在,尤其对于大表,应该建立合适的索引以避免FTS的产生。我们来看这两张表的索引信息:

select index_name,column_name from dba_ind_columns where table_name like 'XSTFXPS%'

INDEX_NAME COLUMN_NAME

------------------------------ -----------------------------------

XSTFXPS1_PK DHAO00

XSTFXPS2_PK DHAO00

XSTFXPS2_PK SPDM00

我们看到这两张表除了主键约束外都没有建另外的索引。根据语句的查询情况,我们建立了如下的复合索引:

create index idx_xstfxps1_khdm00_ywrq00 on xstfxps1(khdm00,ywrq00) tablespace indx;

为了使用索引,我们必须对原来的日期字段的条件进行一些调整。因为有个trunc()函数的存在,语句将不会使用到索引。我们只要明白trunc(ywrq00)=trunc(sysdate)事实上等同于ywrq00大于trunc(sysdate),小于trunc(sysdate+1)减去一秒,我们就有了比较好的办法来处理

这个条件。最终改写后的语句如下:

select sum(sl0000)

from xstfxps2 a, xstfxps1 b

where a.dhao00=b.dhao00

and b.khdm00='500000003913'

and b.ywrq00 between trunc(sysdate)

and trunc(sysdate)+1-1/(24*60*60);

Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 SORT (AGGREGATE)

2 1 TABLE ACCESS (BY INDEX ROWID) OF 'XSTFXPS2'

3 2 NESTED LOOPS

4 3 TABLE ACCESS (BY INDEX ROWID) OF 'XSTFXPS1'

5 4 INDEX (RANGE SCAN) OF 'IDX_XSTFXPS1_KHDM00_YWRQ00'

(NON-UNIQUE)

6 3 INDEX (RANGE SCAN) OF 'XSTFXPS2_PK' (UNIQUE)

Statistics

----------------------------------------------------------

0 recursive calls

0 db block gets

3 consistent gets

0 physical reads

0 redo size

210 bytes sent via SQL*Net to client

275 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1 rows processed

我们这时候看逻辑IO已经降为3次,语句的执行计划也符合我们的调整目标,创建的索引产生了比较大的效果。这条语句的调整至此告一段落。

相关文章

第一步:创建一个表、第二步:创建一个自增序列以此提供调用函数、第三步:我们通过创建一个触发器,使调用的方式更加简单2013-11-11

当数据库或PL/SQL在运行时发生错误时,一个异常被PL/SQL运行时引擎自动抛出,oracle有三种方式抛出异常,需要了解的朋友可以祥看本文2012-12-12

Oracle数据库处理多媒体信息...2007-03-03

这篇文章主要介绍了CentOS命令行下装oracle 12c的方法(命令行模式安装),需要的朋友可以参考下2016-09-09

今天小编就为大家分享一篇关于oracle常用分析函数与聚合函数的用法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧2019-01-01

批量导入文本文件在Oracle数据库操作中经常遇见,今天给大家介绍一种通过sqlldr批处理实现的方法,有需要的朋友们可以参考借鉴,下面来一起看看。2016-09-09

这篇文章主要介绍了Oracle 日志挖掘(LogMiner)使用,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下2018-07-07

本篇文章是对系统重装后Oracle数据库完全恢复的解决办法进行了详细的分析介绍,需要的朋友参考下2013-06-06

这篇文章主要介绍了Orcale 数据库客户端PL/SQL 中文乱码的问题解决方法,需要的朋友可以参考下2014-05-05

这篇文章主要介绍了Oracle用decode函数或CASE-WHEN实现自定义排序功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下2020-05-05

最新评论

oracle将千万行查询优化到一秒内,oracle下一条SQL语句的优化过程(比较详细)相关推荐

  1. Oracle sql语句简单优化

    一.操作符优化: 1.IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格.但是用IN的SQL性能总是比较低的,从ORACLE执行的步骤来分析用IN的SQL与不 ...

  2. Oracle SQL语句性能优化方法大全

    下面列举一些工作中常常会碰到的Oracle的SQL语句优化方法: 1.SQL语句尽量用大写的: 因为oracle总是先解析SQL语句,把小写的字母转换成大写的再执行. 2.选择最有效率的表名顺序(只在 ...

  3. 在Oracle中不通过存储过程一次执行多条SQL语句Oracle PL/SQL

    PL/SQL是ORACLE对标准数据库语言的扩展,ORACLE公司已经将PL/SQL整合到ORACLE 服务器和其他工具中了,近几年中更多的开发人员和DBA开始使用PL/SQL,本文将讲述PL/SQL ...

  4. c oracle 多条语句,Oracle 实践:如何编写一条 sql 语句获取数据表的全部索引信息(兼容 Oracle 19c、Oracle 11g)...

    一.引言 部门使用 Oracle 已经有一些时日,最近在工作中遇到了这么一个需求: 我们希望拿到某些数据表的全部索引信息,对索引信息进行检查,检查是否有漏掉没有创建的索引 这个需求,核心的点在于,我需 ...

  5. c#执行多句oracle,C#一次执行多条SQL语句,Oracle11g数据库

    由于经常执行SQL语句,如果一条一条执行效率低下. oarclecmd.CommandText = sqlstr; oraclecmd.ExecuteNonQuery(); sqlstr 可以写成如下 ...

  6. 一图讲解一条sql语句的一生——《收获,不止Oracle》的读书笔记01

    其实也是<收获,不止Oracle>的读书笔记之一啦 微信读书可以看,数据库我觉得相通性还是比较大的,不管你用的哪种,都可以学学 难度的话,我才看到2.2 ,觉得本菜鸟还是可以看懂的. 说是 ...

  7. oracle+执行变量语句,ORACLE sql 语句的执行过程(SQL性能调整)

    第1章 SQL语句处理的过程 在调整之前我们需要了解一些背景知识,只有知道这些背景知识,我们才能更好的去调整sql语句. 本节介绍了SQL语句处理的基本过程,主要包括: · 查询语句处理 · DML语 ...

  8. kettle如何3秒内写入100万条数据到Redis

    kettle如何3秒内写入100万条数据到Redis 1.实现结果 先来看下实现结果,如下图,本地写入100万数据,耗时2.3s,每秒44万.接下来说说如何实现: 数据存储结构样例: 2.添加redi ...

  9. oracle sql语句常用优化方法

    oracle sql语句常用优化方法 最近做一些报表查询,经常做一些小优化,在这里总结一下 语句上的优化: 1.SELECT 语句中避免使用*,用那些字段就摘出哪些. 2.SQL语句尽量用大写: 因为 ...

最新文章

  1. java 网络实验_Java实验五网络编程与安全
  2. winform利用委托传值到datagridview_C# Winform 跨多级窗体/控件传值
  3. Windows 聚焦的锁屏壁纸设置为桌面壁纸
  4. Vue 组件间通信六种方式
  5. html加上百度统计,vue单页面应用加入百度统计
  6. 图解如何制作苹果OS X系统ISO光盘
  7. C++:值传递、指针传递、引用传递
  8. bzoj1150: [CTSC2007]数据备份Backup--贪心+优先队列维护堆
  9. mapreduce排序比较器的选取
  10. android.opengl.GLSurfaceView概述
  11. linux tomcat部署php项目,linux修改tomcat默认访问项目的具体步骤(必看篇)
  12. ubuntu 安装node.js
  13. 【疾病分类】基于matlab GUI模糊逻辑分类叶病严重程度分级系统【含Matlab源码 194期】
  14. Java 接口,多态
  15. “放管服”改革背景下公安车驾管业务办理情况调研
  16. git remote: error: hook declined to update
  17. 异步时钟脉冲同步器的设计
  18. CCF中学生计算机程序设计入门篇练习2.4.2(NOI 1002 三角形) pascal
  19. 路由器 telnet配置
  20. 学习中遇到的小技巧(陆续更新……)

热门文章

  1. JSON和JS对象之间的互转
  2. 自定义的全局公共样式
  3. Dubbo常见面试题与答案
  4. Java多线程面试题与答案
  5. 谈Servlet与JSP
  6. RROR in main Module not found: Error: Can‘t resolve ‘index.js‘
  7. 江苏省计算机一级考试基础知识,江苏省计算机一级考试大纲及复习指南
  8. java 上下文加载器_【深入理解Java虚拟机 】线程的上下文类加载器
  9. ajax解析json中的对象数组对象,在JQuery中检索json数组后获取json对象Ajax
  10. Java常用设计模式————适配器模式