(4)当插入数据量很大时,索引需重新分裂,用更多的数据块来存放索引数据
在插入200606月份的数据后,进行查询并跟踪执行语句所扫描的数据块。查询语句为:select Custld,AcptId,Cusfldl,hsUnit,Dept,Unit from DATA_DEST where Custld='1380745518';插入200606月份的数据后查询跟踪的结果如表4所示:
表4 插入200606月份的数据后查询跟踪的结果
插入200612月份的数据后查询跟踪的结果如表5所示
表5 插入200612月份的数据后查询跟踪的结果
比较表4和表5的黑体部分,可以看到随着相同的值数据插入,索引块出现了迁移。在2006年12月份的时候,同一CustId列数据所在的索引数据块(数据块编号为:5769587、9462046、5771162、548)与6月份时的索引数据块(数据块编号为:5769587、13225043、9462046、5771162、548)是不同的。
3 索引对查询性能的影响
下面分析有18亿条记录的表在单个分区内、多个分区内及全表内使用索引字段的一些表现。以下的查询均基于CustIdl列来查询。考虑到SGA缓存数据在DATA BUFFER对查询的影响,在每次查询前清空SGA中的数据。
(1)单个分区,离散度高的列上的分区索引效率比按高
模拟过程中发现,存在B树索引时,离散度高的列(如
本文原文Cusfld)索引的效率较高,数据量的增长并未造成索引性能的降低。通过ORADEBUG命令DUMP出Oracle内存中DATABUFFER部分的数据块,发现在一个分区内只需4次分裂,索引就可以定位到需要的数据。测试结果如表6所示。
查询语句为:
select Custld,Acptld,Custldl,hsUnit,Dept,Unit from DATA_DEST
where Custldl='1380745518'and FEYM='200610';
表6 单个分区内的根据CustId查询的结果
(2)多个分区内使用索引查询的致年没有差异
在数据插入过程中单独查询某CustIdl在200610,200710,200810三个年月的数据,可以看出:无论对哪个年月进行查询,只要指定查询的CustIdl和Feym条件,查询都是对特定的分区进行扫描,消耗很少(此例中耗时为00:00:00.31)。
(3)全表所有分区的索引扫描尽管效率按高,但由于要扫描所有分区,响应时间相对长
如果只指定CustIdl条件进行查询,则会搜索该表的全部分区,共返回36条记录,耗时0.85秒。测试结果如表7所示。
表7 全表范围索引扫描的输出片断
4 结束语
综上所述,可以得出以下结论与建议:
(1)对于大表(记录超过1亿条)采用Oracle提供的分区特性就可以满足大数据量下的系统性能要求,不必为每个业务单位单独建立一张物理表;
(2)在每个分区5000万条记录的情况下,分区范围内的查询效率较低。对于像CustId这样的在每个分区中离散度都高的列,建议建成分区索引,以保证系统的可维护性以及性能的稳定,并在SQL中尽可能限制查询所需要涉及到的表分区。
(3)如果不是主键列,而且DML语句中多数情况下可以使用分区列作为数据操作条件,则建议建立分区索引。
(4)如果使用分区,分区策略需要根据实际业务需要来确定。比如如果经常按业务单位进行DML操作,有时按业务单位加上年月进行DML操作,则应该进行复合分区:先按业务单位分区,子分区再按年月分区。如果多数情况下是按年月进行DML操作,少数时间是用业务单位进行DML操作,则应考虑先按年月分区,再按业务单位建立子分区。
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
ORACLE中大数据量下索引效率的测试与分析(二)
最新推荐文章于 2024-08-18 14:57:01 发布