昨天有個同事找我看了一段SQL,說是很慢,我首先看了看執行計畫,發現COST很大,但是同時我也發現分區讀取的有很大的問題。表示這樣的:
create table test1( day_id number)partition by range(day_id)( partition part_0 values less than(20130228), partition part_1 values less than(20130301), partition part_2 values less than(20130302), partition part_3 values less than(20130303), partition part_4 values less than(20130304), partition part_5 values less than(20130305), partition part_6 values less than(20130306))
表中的資料如下:
查詢是這樣子的:
select * from test1 where substr(day_id,1,6) = 201302
執行計畫是這樣的:
可以看出來,一口氣把所有的分區都讀上了,但是按照我的想法,應該是唯讀取part_0和part_1這兩個分區。後來我把這個SQL改成了這樣:
select * from test1 where day_id between 20130227 and 20130228
這個時候的執行計畫就是這樣的:
這樣就好了,唯讀取了需要的分區,這樣子查詢效率也有了很大的提高。生產系統中一天會有3GB的資料,所以如果按照第一個SQL寫,那麼就會讀到這個表所有的分區,資料量就非常可觀了,如果唯讀取自己需要的一個月的分區,就要小多了,COST也降低了很多。
我記得以前寫過一個不能用到索引的情況:http://www.cnblogs.com/wingsless/archive/2011/11/19/2255647.html。昨天遇到這個情況以後發現分區也有這樣那樣的限制,還是原來寫的那句話,一定要慎之又慎的寫SQL。http://www.cnblogs.com/wingsless/archive/2013/03/09/2951618.html。