0512-82289966
技术专区
首页 > 技术专区
为什么说索引是必须的
索引是约束机制的一部分。如果将某列(或一组列)标记为表的主键,那么,每次在表中插入行时,Oracle必须检查是否已经存在具有同一主键值的行。如果表的列上不具有索引,那么唯一的办法是扫描整个表,检查每一行。如果表仅有数行,这种做法可以接受,但如果表有数千行或数百万行(或数十亿行),则不可行。通过索引,可以立即(或近乎立即)访问键值,因此,检查存在性几乎可以一挥而就。如果定义了主键约束,而主键列上尚不存在索引,Oracla将自动创建一个。
    唯一约束也需要索引。与主键约束的区别在于,唯一约束的列可以空留。这不影响索引的创建和使用。外键约束通过索引来实施,但索引必须存在于父表中,而并非一定在为其定义约束的表中。外键约束将子表中的列与父表中的主键或唯一键关联起来。在子表中插入行时,Oracle将在父表中查找索引,在确定存在匹配的行后才允许执行插入。但是,为了提高性能,始终应在子表的外键列上创建索引:如果Oracla可以使用索引来确定子表中是否存在引用被删除行的行,那么在父表上执行DELETE操作的速度将大大加快。
    索引对于性能而言至关重要,。在执行包含WHERE子句的任何SQL语句时,Oracle必须确定要选择或修改的行。如果WHERE子句中引出的列上没有任何索引,唯一的途径是扫描整个表,全表扫描将读取表中的每一行,以便找到相关行。如果表有数十亿行,那么将耗用好几个小时。如果相关的列上存在索引,Oracle将改为搜索索引。索引是有序键值列表,其排列方式可使搜索变得更加有效。每个键值是指向表行的指针。如果表超过一定的大小,而且要检索的行的比例低于特定的值,那么,与扫描全表相比,通过索引查找来定位相关行将快的多。如果表较小,或WHERE子句将检索表行的大部分,则全表扫描来的更快:通常可以选择Oracle,应为Oracle可以根据数据库收集的有关表和表行的统计信息,做出是否使用索引的正确决策。
    第二种可以使用索引的情况是排序。如果SELECT语句包含ORDERBY、GROUPBY、UNION或其他一些关键词,则必须按顺序排列行,如果有了索引则可以按正确的顺序返回行,而无需首先对它们进行排序。
    索引有助于提高性能的第三种情况是在连接表时。不过此时,Oracle仍会根据表的大小和可用的内存资源做出选择:将表扫描到内存中并在那里将连接在一起可能比使用索引的速度更快。嵌套循环链接(nested loop join)技术使用另一个表上的索引遍历一个表来定位匹配行,这通常是一个磁盘密集型操作。哈希连接(hash join)技术将整个表读入内存,将其转换为哈希表,然后使哈希算法定位匹配的行,这是一个内存和CPU更为密集型的操作。排名合并连接(sort merge join)在连接列上排序表,然后将它们合并在一起:这通常是磁盘、内存和CPU资源之间的折中。如果没有索引Oracle将在可用的连接技术方面受到严重限制。