使用索引優化StopKey

壹頁書發表於2014-06-16
今天遇到一個調優的問題。
模擬的表結構如下:
  1. create table test
  2. (
  3.  id int primary key,
  4.  name varchar2(10),
  5.  createtime date
  6. );

  7. insert into test select rownum,rownum,sysdate-rownum from dual connect by level<100000;
目標資料庫是Oracle。
查詢的SQL不算複雜,就是查詢一個表最後建立的幾條記錄。
  1. SELECT *
  2. FROM (
  3.     SELECT A.*, ROWNUM AS RN
  4.     FROM (
  5.         SELECT *
  6.         FROM test
  7.         ORDER BY createtime DESC
  8.     ) A
  9.     WHERE ROWNUM <= 20
  10. )
  11. WHERE RN >= 10
我先看了一下執行計劃,發現走的是全表掃描。

我感覺在CreateTime欄位上建立一個索引,就應該可以了,可實際上不行。


執行計劃沒有變。

索引列設定為非空 就可以解決這個問題了。

設定CreateTime欄位為非空,並且分析模式。

檢視執行計劃,已經走索引了。


---分割線

這個問題在MySQL裡面,就容易處理了。因為MySQL的索引包括空值。
但是通過簡單的建立索引,還是不能達到優化的效果。

通過JAVA程式初始化資料,然後建立索引,檢視執行計劃

可以看到,單純的建立一個索引是沒有效果的。
可以使用延遲關聯的方式
  1. select a.* from
  2. test a
  3. inner join
  4. (
  5.     select id from test order by createtime desc limit 10,10
  6. ) b
  7. on(a.id=b.id)
  8. order by a.createtime desc;
執行計劃如下:

可以看到已經應用了索引,達到了優化的目的。

總之,Oracle的索引列儘量設定為非空,會省不少心。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1184340/,如需轉載,請註明出處,否則將追究法律責任。

相關文章