昨天有个同事找我看了一段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。