博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用合适的索引避免不必要的全表扫描
阅读量:6734 次
发布时间:2019-06-25

本文共 3806 字,大约阅读时间需要 12 分钟。

        Oracle数据库里大部分SQL优化的问题都可以增加或减少索引的方式来解决,但这绝不是全部。当目标SQL语句所要查询的只是目标表中的一部分数据时,通过创建合适的索引就能够避免在没有索引的情况下为查询这一小部分数据而不得不采用全表扫描的操作,这样就降低了目标SQL语句的资源消耗,同时也会缩短了执行时间。

    创建一张测试表及创建一个普通的单键值B树索引:

SQL> create table t1 as select * from dba_objects;Table created.SQL> create index idx_t1 on t1(object_id);Index created.

       清空缓存数据,我们看下一个SQL查询的执行计划及资源消耗:

SQL> alter system flush buffer_cache;System altered.SQL> set timing onSQL> set autotrace traceonlySQL> select * from t1 where object_id is null;no rows selectedElapsed: 00:00:00.11Execution Plan----------------------------------------------------------Plan hash value: 3617692013--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |    12 |  2484 |   291   (1)| 00:00:04 ||*  1 |  TABLE ACCESS FULL| T1   |    12 |  2484 |   291   (1)| 00:00:04 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("OBJECT_ID" IS NULL)Note-----   - dynamic sampling used for this statement (level=2)Statistics----------------------------------------------------------        308  recursive calls          0  db block gets       1151  consistent gets     1038  physical reads          0  redo size       1183  bytes sent via SQL*Net to client        405  bytes received via SQL*Net from client          1  SQL*Net roundtrips to/from client          0  sorts (memory)          0  sorts (disk)          0  rows processed

      从上面的查询中可以看到,SQL语句查询走的全表扫描,有1151个一致性读,1038个物理读。

   为什么没有走索引哪?

   原来对于普通的单键值B树索引而言,NULL值不入索引的,所以即便在OBJECT_ID上有单键值B树索引IDX_T1,在执行上面的查询时也用不上。对于上面的SQL有没有办法让其走索引那?如果你对Oracle数据库里B树索引的结构和原理都很了解的话就不难回答这个问题。

   这里只需建立一个复合B树索引就可以了。

   删除原来的IDX_T1索引,重新创建一个同名的复合B树索引IDX_T1,其前导列依然是object_id,但第二列是一个常数0,这里利用的原理是---虽然对于单键值B树索引而言NULL值不入索引,但对于复合B树索引来说,NULL值是入索引的。

SQL> drop index idx_t1;Index dropped.SQL> create index idx_t1 on t1(object_id,0);Index created

 

     重新执行同样的SQL查询:

SQL> alter system flush buffer_cache;System altered.Elapsed: 00:00:00.11SQL>  SQL> select * from t1 where object_id is null;no rows selectedElapsed: 00:00:00.01Execution Plan----------------------------------------------------------Plan hash value: 50753647--------------------------------------------------------------------------------------| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------------------|   0 | SELECT STATEMENT            |        |    12 |  2484 |    97   (0)| 00:00:02 ||   1 |  TABLE ACCESS BY INDEX ROWID| T1     |    12 |  2484 |    97   (0)| 00:00:02 ||*  2 |   INDEX RANGE SCAN          | IDX_T1 |  4314 |       |    11   (0)| 00:00:01 |--------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   2 - access("OBJECT_ID" IS NULL)Note-----   - dynamic sampling used for this statement (level=2)Statistics----------------------------------------------------------          0  recursive calls          0  db block gets          2  consistent gets          2  physical reads          0  redo size       1183  bytes sent via SQL*Net to client        405  bytes received via SQL*Net from client          1  SQL*Net roundtrips to/from client          0  sorts (memory)          0  sorts (disk)          0  rows processed

         创建复合索引重新执行后可以看到Oracle这次查询就用到了B树复合索引IDX_T1,数据从全表扫描变成了索引范围扫描,数据耗费时间、一致性读和物理读也大幅度下降了。
     通过创建合适的索引来避免不必要的全表扫描,大幅降低了目标SQL 语句的资源消耗,进而大幅度的缩短了SQL的执行时间。

                                                                                                     --摘自崔华基于Oracle的SQL优化

转载于:https://www.cnblogs.com/myrunning/p/4837559.html

你可能感兴趣的文章
菜鸟Scrum敏捷实践系列(三)用户故事的组织---功能架构的规划
查看>>
让ubuntu开启ssh服务以及让vi/vim正常使用方向键与退格键
查看>>
python中的null值
查看>>
ssm jQuery 获取checkbox选中的值form表单提交例子
查看>>
JavaEE(17) - JPA查询API和JPQL
查看>>
简单方法编写在群晖ds218play上运行的sh
查看>>
ubuntu16.04下ftp服务器的安装与配置
查看>>
机器学习模型评估指标汇总
查看>>
C语言通过timeval结构设置周期
查看>>
LeetCode155-最小栈(优先队列/巧妙的解法)
查看>>
【转】删除cookie
查看>>
木其工作室代写程序 [原]当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'TB_TABLENAME' 中的标识列插入显式值。...
查看>>
[洛谷P2161][SHOI2009]会场预约
查看>>
'用户 'sa' 登录失败。该用户与可信 SQL Server 连接无关联,做JSP项目连接数据库 ....
查看>>
javascript中substring和substr方法
查看>>
C# FTPHelper帮助类
查看>>
以色列之光
查看>>
Photo1
查看>>
学习方法及笔记的总结
查看>>
AHK GUI开发示例
查看>>