讓天下沒有難用的資料庫 » 查詢表中最新紀錄
今天開發給了一條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