暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle索引的基本原理(一)索引的基本概念

原创 大柏树 2022-12-30
1499

当访问表中的数据时,oracle提供了两种方式:

  • 从表中读取所有行(即全表扫描);
  • 通过ROWID一次读取一行;

当访问大数据量表中的少量行时,应该使用索引。例如:如果只访问大数据量表中5%的行,通过使用索引标识需要读取的数据块,这样花费IO较少。如果没有索引,就要读取表中所有的数据块,当然了,如果使用了INMEMORY选项(12c新特性),那就另当别论了。

索引对性能改进的程度取决于数据的选择性以及数据在表中的数据块的分布方式。如果数据的选择性很好,那么表中将只有很少的行匹配一个索引值(例如护照号码)。Oracle将能够快速查询索引,找到匹配索引值的ROWID。从而快速查到表中相应的少量数据块。如果数据的选择性不好(例如国家名),那么对一个索引值可能返回许多ROWID,导致从表中查询许多不连续的数据块。

如果数据的选择性很好,但是相关的行在表中的物理存储位置并不互相靠近,这种情况下,索引带来的好处就会大打折扣。如果匹配索引值的数据分散在表的多个数据块中,就必须从表中把每个数据块都选出来以得到需要的查询结果。有些情况下,你会发现当数据分散在表的多个数据块中时,最好不使用索引,而是选择全表扫描(或是做IMMEMORY扫描)。
执行全表扫描时,Oracle使用多块读的方式以快速扫描表。基于索引的读是单块读,因此使用索引的目标是减少完成查询所需的单块读的数量。

通过利用Oracle的一些可用选项,比如分区、并行DML、并行查询记忆调整DB_FILE_MULTIBLOCK_READ_COUNT来进行更大的IO操作,全表扫描和索引查找之间的平衡点正发生着改变。
硬件变的更为快速,在磁盘的高速缓存中可以缓存更多的信息,内存和闪存也变的更为廉价。于此同时,Oracle已经增强的索引特性,包括跳跃式索引扫描和其他内部操作,可用来减少返回数据所需的时间。

索引能提高查询的性能。select语句以及update和delete语句的where子句(当访问的行较少时)可以借助索引来提高性能。一般来说,增加索引会降低insert语句的性能(因为需要同时对表和索引进行操作)。索引列上的update操作将比没有加索引慢很多,因为数据库必须同时管理对表和索引的改动。此外,针对大量行的delete操作将会由于表中存在索引而变慢。

一条删除表中一半数据的delete语句同时需要删除这些行对应的所有索引(这种情况是非常耗时的)。通常来说,在表上加一个索引会使该表上insert操作的执行时间变为原来的三倍;在加一个索引就会再慢一倍;然而,一个由两列组成的复合索引并不比只有一列的索引差很多。索引列的update和delete操作同样也会变慢。需要平衡索引带来的查询性能的提升和对数据修改性能的影响。

通过查询DBA_INDEXES视图可获得一个表上所有索引的清单,也可以访问user_indexes视图来查看当前方案(schema)的索引。查询ALL_INDEXES视图可以查看你能够访问的所有表的索引。

SQL> create index emp_id1 on emp(empno,ename,deptno); Index created. SQL> create index emp_id2 on emp(sal); Index created. SQL>

通过user_indexes(也可以使用dba_indexes)来查询emp表上新建的索引。

SQL> select table_name,index_name from user_indexes where table_name='EMP'; TABLE_NAME INDEX_NAME ------------------------------ ------------------------------ EMP PK_EMP EMP EMP_ID2 EMP EMP_ID1 SQL>

可以看到索引的名字,但是看不到每个索引包含的列,为了获得当前用户的表中被索引列的信息,可以查询USER_IND_COLUMNS视图。DBA可以通过DBA_IND_COLUMNS视图检索所有方案中被索引的列,而通过ALL_IND_COLUMNS视图可以查看当前用户有权看到的所有表的被索引列。

SQL> col index_name for a12 SQL> col column_name for a8 SQL> col table_name for a8 SQL> select table_name,index_name,column_name,column_position 2 from user_ind_columns 3 order by table_name,index_name,column_position; TABLE_NA INDEX_NAME COLUMN_N COLUMN_POSITION -------- ------------ -------- --------------- DEPT PK_DEPT DEPTNO 1 EMP EMP_ID1 EMPNO 1 EMP EMP_ID1 ENAME 2 EMP EMP_ID1 DEPTNO 3 EMP EMP_ID2 SAL 1 EMP PK_EMP EMPNO 1 6 rows selected. SQL>
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论