这段时间,一直在做数据库方面的调优。
其中有一个表,差不多1亿多数据,做了表分区,每天40多万数据增长。分区一个月做一次,相当于一个分区有1200万左右数据。
前台限制查询区间为7天,也就是最多数据为280万,这时,查询走的是分区key创建时间,选择因子差不多为23%。
前台也做了分页,这样,基本上能够保证走的是索引。
查询7天,一次返回3000条,差不多1100ms左右。返回200条,时间就基本在几百ms。
需要注意的是,oracle的硬解析与软解析。
这里,先介绍oracle的执行计划过程,如下:
1.执行语句,语义,安全等检查
2.生成父游标,父游标只跟语句文本相同,可以认为就是传入的sql文本,放入共享缓存
3.生成子游标,即整个执行计划,这需要查询优化器根据具体的信息,如选择性如何,来决定是否走索引还是全表等。子游标会放入共享缓存。
假设我们提交一条查询语句:
select * from student t where t.id ?
这时经过上述3步,会生成共享的父游标(单纯sql文本)与子游标(整个执行计划)
之后,我们再提交select * from student t where t.id ?,这条语句查询时,会重用父游标与子游标,也就是说不再进行执行计划解析。
这个,在数据量小时是可以的,但是当数据量很大,并且用户查询的数据量范围不可控时会造成很大性能问题。
考虑业务中一个表有1200万条数据,第一个用户查询时查询了400万条数据范围,选择因子为33%。这导致了数据库走了全表扫描,也将执行计划进行了缓存。
然后第二个用户用同样的sql再进行查询,查询数据范围为200万,尽管这时选择因子为16%,但由于在共享缓存中存在父子游标,因此还是走全表扫描。
在我们业务中,由于前台限制了查询数据量最大为280万,而单个分区表数据量为1200万,也就是说最坏情况的选择因子也才23%,因此走的始终是索引扫描。
所以这种情况,用绑定参数使oracle进行软解析是有效的。
否则,对于大数据查询来讲,慎用绑定参数。