查询表中最新纪录-减少表扫描量

简介:

 今天开发给了一条sql,查询表中最近更新的一条记录:

       select id,
       type,
       object_id,
       nick,
       isv_id,
       next_auditor_role,
       status,
       apply_parameters,
       comments,
       gmt_create,
       gmt_modified
      from (select id,
                type,
                object_id,
                nick,
                isv_id,
                next_auditor_role,
                status,
                apply_parameters,
                comments,
                gmt_create,
                gmt_modified
          from tops_apply
          where object_id = 552
          and status = 1
          order by gmt_create desc)
 where rownum = 1

一看这条sql就有优化的余地,内层查询查询了大量无用的数据。

2.创建索引:
17:02:07 SQL> create index ind_tops_apply_oid_sts_create1 on tops_apply(object_id,status,gmt_create)
17:02:30   2  tablespace tbs_top_ind
17:02:30   3  compute statistics;

3.执行sql
17:02:31 SQL> select id,
17:02:42   2         type,
17:02:42   3         object_id,
17:02:42   4         nick,
17:02:42   5         isv_id,
17:02:42   6         next_auditor_role,
17:02:42   7         status,
17:02:42   8         apply_parameters,
17:02:42   9         comments,
17:02:42  10         gmt_create,
17:02:42  11         gmt_modified
17:02:42  12    from (select id,
17:02:42  13                 type,
17:02:42  14                 object_id,
17:02:42  15                 nick,
17:02:42  16                 isv_id,
17:02:42  17                 next_auditor_role,
17:02:42  18                 status,
17:02:42  19                 apply_parameters,
17:02:42  20                 comments,
17:02:42  21                 gmt_create,
17:02:42  22                 gmt_modified
17:02:42  23            from tops_apply
17:02:42  24           where object_id = 552
17:02:42  25             and status = 1
17:02:42  26           order by gmt_create desc)
17:02:42  27   where rownum = 1;
 
         13  consistent gets
  
4.查询有13个逻辑读,改写sql,换成rowid形式来取结果:
17:02:44 SQL>  select id,
17:02:59   2          type,
17:02:59   3          object_id,
17:02:59   4          nick,
17:02:59   5          isv_id,
17:02:59   6          next_auditor_role,
17:02:59   7          status,
17:02:59   8          apply_parameters,
17:02:59   9          comments,
17:02:59  10          gmt_create,
17:02:59  11          gmt_modified
17:02:59  12     from tops_apply t, (select rid from (select rowid rid
17:02:59  13             from tops_apply
17:02:59  14            where object_id = 552
17:02:59  15              and status = 1
17:02:59  16            order by gmt_create desc) where rownum<2)tt where tt.rid=t.rowid;

 
          3  consistent gets

5.改写查询后,只有3个逻辑读,但是一个很简单的查询,但写出来的sql有些复杂,能不能有办法改进一下;在执行计划中看到了:
 INDEX RANGE SCAN DESCENDING| IND_TOPS_APPLY_OID_STS_CREATE1
 oracle很聪明的在order by gmt_create desc的时候对索引进行了descending扫描,在仔细想一想这条sql的目的是找出表中的最新记录, 而索引在创建的时候是有序的,这样就可以利用索引的有序性来查找出结果,oracle也只需要扫描索引的第一行(descending建索引)或者索引最后一行(默认 ASCEDING建索引 ),改写sql:

A.select id,
               type,
               object_id,
               nick,
               isv_id,
               next_auditor_role,
               status,
               apply_parameters,
               comments,
               gmt_create,
               gmt_modified
          from tops_apply
          where object_id = 552
          and status = 1 and rownum<2 order by gmt_create desc ;
         (index(object_id,status,gmt_create))
          执行计划:INDEX RANGE SCAN DESCENDING)
B.select id,
               type,
               object_id,
               nick,
               isv_id,
               next_auditor_role,
               status,
               apply_parameters,
               comments,
               gmt_create,
               gmt_modified
    from tops_apply
    where object_id = 552 and status = 1  and rownum<2;
    (index(object_id,status,gmt_create desc))
    执行计划:INDEX RANGE SCAN)

目录
相关文章
|
15天前
|
存储 关系型数据库 索引
10. 在一个非主键字段上创建了索引, 想要根据该字段查询到数据, 需要查询几次 ?
在非主键字段上创建索引,查询数据通常需两次。对于MyISAM,先通过索引找到数据行指针,再获取数据;而InnoDB则先找主键ID,再从主键索引中查找数据。
11 0
|
8月前
|
SQL 分布式计算 MaxCompute
一次性查询一张表所有字段的空值率
一次性查询一张表所有字段的空值率
780 2
|
9月前
|
存储 关系型数据库 MySQL
mysql百万级数量插入、删除、分组、分页、更新语句优化
mysql百万级数量插入、删除、分组、分页、更新语句优化
|
11月前
|
关系型数据库 MySQL 索引
一个表中索引的数量是不是越多越好?
往InnoDB表新增数据时,都会基于主键给自动建立聚簇索引。 随着我们不停的在表里插入数据,会不停的在数据页里插入数据。一个数据页放满后,就会分裂成多个数据页,这时就需要索引页去指向各个数据页。
97 0
|
SQL 关系型数据库 MySQL
[MySQL优化案例]系列 — 索引、提交频率对InnoDB表写入速度的影响
[MySQL优化案例]系列 — 索引、提交频率对InnoDB表写入速度的影响
103 0
[MySQL优化案例]系列 — 索引、提交频率对InnoDB表写入速度的影响
|
存储 SQL 缓存
为什么索引可以让查询变快?终于有人说清楚了!
上表是一张真实的数据库表,其中每一行是一条记录,每条记录都有字段。假设上面的数据库是一个有10万条记录的大数据库。现在,我们想从10万条记录中搜索一些内容,那么挨着一个一个搜索无疑将花费很长的时间,这个时候我们在数据结构与算法里学的二分查找法就派上了用场。
为什么索引可以让查询变快?终于有人说清楚了!
|
SQL 存储 缓存
|
SQL 算法 索引
SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)
原文:SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)   本文出处:http://www.cnblogs.com/wy123/p/6008477.html    关于统计信息对数据行数做预估,之前写过对非相关列(单独或者单独的索引列)进行预估时候的算法,参考这里。
1012 0