1. 程式人生 > >讓天下沒有難用的資料庫 » 查詢表中最新紀錄

讓天下沒有難用的資料庫 » 查詢表中最新紀錄

    今天開發給了一條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)

3  consistent gets