前几天,一个用户找到我,说查一个小表的时候非常慢,我问有多慢,他说最快也得半个小时才能出结果,有时干脆不出结果,我说小表多大,他说就几十兆,有点疑惑,让他帮忙获取了相关信息,一看就明白了,原来所谓的小表是“假”的,下面是分析时参照的信息及分析的步骤。

SQL语句:
select * from t_rec where rec_date>trunc(sysdate-1);

SQL计划:
------------------------------------------------------------------------------------------------------------
| Id  | Operation                | Name            | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |                 |  2011 |   318K|   892   (3)| 00:00:13 |       |    |
|   1 |  PARTITION RANGE ITERATOR|                 |  2011 |   318K|   892   (3)| 00:00:13 |   KEY |  21 |
|*  2 |   TABLE ACCESS FULL      | T_REC |  2011 |   318K|   892   (3)| 00:00:13 |   KEY | 21 |
------------------------------------------------------------------------------------------------------------

表所占空间:
select sum(bytes)/1024/1024 "(MB)" from dba_extents where segment_name='T_REC';
      (MB)
----------
    38.675

看到这里,我有点疑惑,表确实不大,但有个线索,大家注意到没有,那就是partition,如此小的表,有必要分区吗?莫非。。。

desc t_rec

名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 REC_ID                                    NOT NULL VARCHAR2(20)
 REC_NAME                                           VARCHAR2(200)
 REC_DESC                                           CLOB
 REC_DATE                                  NOT NULL DATE
 REC_CLASS                                          NUMBER
 REC_LEN                                            NUMBER

至此,真相大白了,大家明白了吧?也许有的同学还是不明白,继续。。。

select sum(bytes)/1024/1024/1024 "(GB)" from dba_extents 
where partition_name in(
select lob_partition_name from user_lob_partitions
where table_name='T_REC');
      (GB)
----------
309.31425

明白了吗?呵呵,现在通过上面的信息,我们找到了”小表超慢“的原因,但这时,用户再次提出:我们怎么解决这个查询慢的问题呢?继续。。。

select index_name,table_name,column_name from user_ind_columns where table_name='T_REC'

INDEX_NAME                     TABLE_NAME                     COLUMN_NAME
------------------------------ ------------------------------ ----------------------------------------
IDX1_REC_DATE                   T_REC                          REC_DATE
IDX2_REC_ID                     T_REC                          REC_ID

因为该库为用户生产库,且该表较大,所以,决定先通过hint测试效率问题:
select /*+ index(t IDX1_REC_DATE)*/ * from t_rec t where rec_date>trunc(sysdate-1);

加hint后计划:
---------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                          | Name                 | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
---------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                   |                      |  2011 |   318K|   912   (1)| 00:00:15 |       |       |
|   1 |  PARTITION RANGE ITERATOR          |                      |  2011 |   318K|   912   (1)| 00:00:15 |   KEY |     21 |
|   2 |   TABLE ACCESS BY LOCAL INDEX ROWID| T_REC      |  2011 |   318K|   912   (1)| 00:00:15 |   KEY |     21 |
|*  3 |    INDEX RANGE SCAN                | IDX1_REC_DATE|  2011 |       |    14   (0)| 00:00:01 |   KEY |     21 |

hint生效,测试2秒出结果,征求用户意见,用户说这样可以,至此问题解决,大家可以参照学习,禁止转载。

十分钟释疑Oracle中“小表超慢”之谜(SQL调优/SQL优化)的更多相关文章

  1. 【转】Oracle中dual表的用途介绍

    原文:Oracle中dual表的用途介绍 [导读]dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录.我们可以用它来做很多事情. dual是一个虚拟表, ...

  2. oracle 中删除表 drop delete truncate

    oracle 中删除表 drop delete truncate   相同点,使用drop delete truncate 都会删除表中的内容 drop table 表名 delete from 表名 ...

  3. 如何在Oracle中建立表和表空间?

    1.建表空间 ORACLE中,表空间是数据管理的基本方法,所有用户的对象要存放在表空间中,也就是用户有空间的使用权,才能创建用户对象.否则是不充许创建对象,因为就是想创建对象,如表,索引等,也没有地方 ...

  4. 向oracle中的表插入数据的方法

    向oracle中的表插入数据的方法有以下几种: 假设表名为User 第一种方法:select t.*,rowid from User t;-->点击钥匙那个标记就可向表中添加数据 第二种方法:s ...

  5. 十分钟理解Java中的动态代理

    十分钟理解 Java 中的动态代理   一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道 ...

  6. Oracle中truncate表不更新last_ddl_time列

    Oracle中truncate表不更新last_ddl_time列 问题描述 最近发现数据库中定时job的某张表,每天都有truncate动作,由于调整了job的interval时间,想查看last_ ...

  7. Oracle中SQL调优(SQL TUNING)之最权威获取SQL执行计划大全

    该文档为根据相关资料整理.总结而成,主要讲解Oracle数据库中,获取SQL语句执行计划的最权威.最正确的方法.步骤,此外,还详细说明了每种方法中可选项的意义及使用方法,以方便大家和自己日常工作中查阅 ...

  8. Oracle SQL调优之分区表

    目录 一.分区表简介 二.分区表优势 三.分区表分类 3.1 范围分区 3.2 列表分区 3.3 散列分区 3.4 组合分区 四.分区相关操作 五.分区相关查询 附录:分区表索引失效的操作 一.分区表 ...

  9. Oracle SQL 调优健康检查脚本

    Oracle SQL 调优健康检查脚本 我们关注数据库系统的性能,进行数据库调优的主要工作就是进行SQL的优化.良好的数据架构设计.配合应用系统中间件和写一手漂亮的SQL,是未来系统上线后不出现致命性 ...

随机推荐

  1. ORA-00900: invalid SQL statement

    1.错误描述 SQL> startup;        startup        ORA-00900: invalid SQL statement 2.错误原因 3.解决办法

  2. org.hibernate.MappingException

    1.错误描述 org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'sessio ...

  3. CSS开启硬件加速提高网站性能

    国外一篇文章,有点意思,转载过来,准备尝试下~ 中文地址:http://www.cnblogs.com/yzw7489757/ 原文地址:http://blog.teamtreehouse.com/i ...

  4. 内置函数:filter函数

    功能: filter函数用于过滤序列,将满足条件的元素取出来构成新的序列. 用法: filter(function, iterable) 接受两个参数,第一个函数为过滤函数(返回True后者False ...

  5. springboot集成Actuator

    Actuator监控端点,主要用来监控与管理. 原生端点主要分为三大类:应用配置类.度量指标类.操作控制类. 应用配置类:获取应用程序中加载的配置.环境变量.自动化配置报告等与SpringBoot应用 ...

  6. sqoop将mysql连表查询结果导入hdfs文件

    sqoop import --connect jdbc:mysql://ip/数据库 --username 用户名 --password 密码 --query " select p.bidN ...

  7. MyISAM和InnoDB索引实现区别

    首先来讲MyISAM: MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址.下图是MyISAM索引的原理图: 这里设表一共有三列,假设我们以Col1为主键,则上图是 ...

  8. Redis总结(七)Redis运维常用命令

    redis 服务器端命令 redis 127.0.0.1:6380> time  ,显示服务器时间 , 时间戳(秒), 微秒数 1) "1375270361" 2) &quo ...

  9. POJ 1087 A Plug for UNIX (网络流,最大流)

    题面 You are in charge of setting up the press room for the inaugural meeting of the United Nations In ...

  10. oracle数据库和表的操作

    一.字符函数 (1)连接符 concat --连接符 select concat('10086','-')||'1531234567' 电话号 from dual; (2)首字母大写 initcap ...