码迷,mamicode.com
首页 > 其他好文 > 详细

14.1 Understanding Index Performance 了解索引性能

时间:2015-08-07 20:09:10      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:性能

14.1.1 Tuning the Logical Structure(优化逻辑结构)


 

不管查询是否使用,SQL引擎必须继续维护一个表上定义的所有索引,在写操作比较频繁的应用中,索引维护工作可能会占用大量的CPUI/O资源,所以,不要建立不必要的索引。


为了最优化性能,删除不必要的索引。在你的数据库执行有代表性的工作量时,使用ALTER INDEX MONITORINGUSAGE来监测索引的使用情况,这个监控功能记录索引是否被使用,如果你发现某索引未被使用就可以删掉它。注意要确保你是在数据库执行有代表性的工作时进行的监测,以免某索引是被使用的,但由于没有被监测到而误删除。


还有,有些索引的使用没办法在执行计划中明显的看到,比如主表上的一个外键索引,它防止从子表中取出共享锁。(防止在子表上加锁?)(这段不太明白什么意思)


如果你正在决定是否要创建一个新的索引来优化性能,那你还可以使用EXPLAIN PLAN语句来决定查询优化器在执行语句的时候是否会用这些索引。如果你创建一个新的索引来优化一个正在被解析的语句的话,Oracle会使这个语句无效。当这个语句下次被解析时,优化器会自动选择会使用新的索引的执行计划。如果你在远程数据库上创建了一个优化分布式语句的索引,优化器会在这个语句下次解析的时候考虑使用这些索引。


有一点需要注意,你创建一个索引来优化一个语句时,可能会影响到其他语句的执行。比如,你为一个语句创建了索引,查询优化器在执行应用中的其他语句的时候也可能使用这个索引。所以,在优化完你最初想要优化的语句后,建议重新测试应用的性能和执行计划,并且重新执行SQL trace ,确保性能是得到了总体的提高。


原文:

Although query optimization helps avoid the use ofnonselective indexes within query execution, the SQL engine must continue tomaintain all indexes defined against a table, regardless of whether queriesmake use of them. Index maintenance can present a significant CPU and I/Oresource demand in any write-intensive application. In other words, do notbuild indexes unless necessary.


To maintain optimal performance, drop indexes that an application is not using. You canfind indexes that are not being used by using the ALTER INDEX MONITORINGUSAGE functionalityover a period that is representative of your workload. This monitoring featurerecords whether an index has been used. If you find that an index has not beenused, then drop it. Make sure you are monitoring a representative workload toavoid dropping an index which is used, but not by the workload you sampled.

 

Also, indexes within an application sometimes haveuses that are not immediately apparent from a survey of statement executionplans. An example of this is a foreign key index on a parent table, whichprevents share locks from being taken out on a child table.

 

If you are deciding whether tocreate new indexes to tune statements, then you can also use the EXPLAIN PLAN statement to determine whether the optimizer chooses touse these indexes when the application is run. If you create new indexes totune a statement that is currently parsed, then Oracle Database invalidates thestatement.


When the statement is next parsed, the optimizerautomatically chooses a new execution plan that could potentially use the newindex. If you create new indexes on a remote database to tune a distributedstatement, then the optimizer considers these indexes when the statement isnext parsed.


Note that creating an index to tune one statement canaffect the optimizer‘s choice of execution plans for other statements. Forexample, if you create an index to be used by one statement, then the optimizercan choose to use that index for other statements in the application as well.For this reason, reexamine the application‘s performance and execution plans,and rerun the SQL trace facility after you have tuned those statements that youinitially identified for tuning.


14.1.2 Index Tuning using the SQLAccess Advisor

(使用SQL ACCESS ADVISOR进行索引优化)

还可以使用另一种方式进行手工索引选择,那就是SQL ACCESS ADVISOR,它可以通过EM访问或者调用DBMS_ADVISOR 包来访问,SQL Access Advisor可以使用已有工作量(workload)或者为某个schema生成假想工作量(hypothetical workload)来提供建议。

 

工作量的来源很多,比如SQL Cache中的现有内容,用户定义的一个SQL语句的集合,或者是一个SQLtuning set(STS)。针对一个工作量SQL Access Advisor会生成一系列建议,你可以从中选择要使用和实现的索引。SQL AccessAdvisor还提供了使用和实现这些索引的脚本,可以手动执行也可以通过EM自动执行。


原文:SQL Access Advisor is an alternativeto manually determining which indexes are required. This advisor recommends aset of indexes when invoked from Oracle Enterprise Manager or run through the DBMS_ADVISOR package APIs. SQL Access Advisor either recommendsusing a workload or it generates a hypothetical workload for a specifiedschema.


Various workload sources are available, such as thecurrent contents of the SQL cache, a user-defined set of SQL statements, or aSQL tuning set. Given a workload, SQL Access Advisor generates a set ofrecommendations from which you can select the indexes to be implemented. Animplementation script is provided that can be executed manually orautomatically through Oracle Enterprise Manager.

 

 

14.1.3 Choosing Columnsand Expressions to Index

(选择要索引的列和表达式)

在哪一列或者表达式上创建索引,那么它就是索引的key。选择索引的key时遵从下面的原则:

  • 选择在where自己中出现频率高的作为key
  • 选择在连接中经常用到的字段
  • 索引选择性高的列(该列的数值重复率低),相同的索引key关联的行越少,索引越优。
  • 当在表上创建唯一或者是主键约束时候,oracle会在该列自动创建索引。
  • 不要在有大量重复值的列上创建标准的B- tree索引,这样的索引选择性很低,因为一个索引key可能关联多个行,除非你经常检索的列恰巧重复的值很少。这种情况下可以使用bitmap索引(位图索引)来提高性能,不过位图索引不要用在经常更新的情形下,比如一个高并发的OLTP系统并不合适。
  • 不要索引经常更新的列。在创建了索引的表上插入,删除以及更新索引列的操作都比在不创建索引的表上操作要慢。这种情况下SQL语句呀同时更新数据表中的数据和索引数据,并且会多创建redoundo数据。
  •  不要索引只在where子句的函数或者操作符中出现的列。当where子句中使用函数时,除了MIN或者MAX,或者索引列和一个运算符的组合,其他情况都不使用索引,当然除了基于函数的索引。
  • 当对主表和子表会进行大量的增删改操作时,考虑在主表和子表间的外键上建立索引,使用这种索引在主表上进行更新和删除操作时可用不用在子表上加共享锁。
  •  当选择创建索引时,要考虑到查询性能提升的同时,增删改的性能会降低,并且索引也要占用额外的空间。如果你想要对比使用索引和不使用索引的性能,可用使用SQL trace来查看sql运行需要的时间。

原文:A key is a column or expression on whichyou can build an index. Followthese guidelines for choosing keys to index:

  • Consider indexing keys that appear frequently in WHERE clauses. 
  • Consider indexing keys that frequently join tables in SQL statements. For more information on optimizing joins, see the "Using Hash Clusters for Performance".
  • Choose index keys that have high selectivity. The selectivity of an index is the percentage of rows in a table having the same value for the indexed key. An index‘s selectivity is optimal if few rows have the same value.
    Note:
    Oracle Database automatically creates indexes, or uses existing indexes, on the keys and expressions of unique and primary keys that you define with integrity constraints. Indexing low selectivity columnscan be helpful when the data distribution is skewed so that one or two valuesoccur much less often than other values.
  • Do not use standard B-tree indexes on keys or expressions with few distinct values. Such keys or expressions usually have poor selectivity and therefore do not optimize performance unless the frequently selected key values appear less frequently than the other key values. You can use bitmap indexes effectively in such cases, unless the index is modified frequently, as in a high concurrency OLTP application.
  • Do not index frequently modified columns. UPDATE statements that modify indexed columns and INSERT and DELETE statements that modify indexed tables take longer than if there were no index. Such SQL statements must modify data in indexes and data in tables. They also create additional undo and redo.

 

  • Do not index keys that appear only in WHERE clauses with functions or operators. A WHERE clause that uses a function, other than MIN or MAX, or an operator with an indexed key does not make available the access path that uses the index except with function-based indexes.
  • Consider indexing foreign keys of referential integrity constraints in cases in which a large number of concurrent INSERTUPDATE, and DELETE statements access the parent and child tables. Such an index allows UPDATEs and DELETEs on the parent table without share locking the child table. 
  • When choosing to index a key, consider whether the performance gain for queries is worth the performance loss for INSERTs, UPDATEs, and DELETEs and the use of the space required to store the index. You might want to experiment by comparing the processing times of the SQL statements with and without indexes. You can measure processing time with the SQL trace facility.
    See Also:
    Oracle Database Advanced Application Developer‘s Guide for more information on the effects of foreign keys on locking


14.1.4 Choosing Composite Indexes 选择组合索引

组合索引包含多个列。组合索引相较单列索引有如下优点:

  • 提高了选择性。有时候选择每单个列其选择性都很差的时候,把这些列组合在一起形成组合索引可以提高选择性。
  • 降低I/O 。当一个查询中要返回的列都包含在组合索引中的时候,oracle直接从索引中返回数据,不必再访问数据表了。
 当语句中包含组合索引开头部分的时候,oracle会使用该组合索引。索引的开头部分是指在定义索引语句(create index)中最先指定的一列或者连续的几个列。考虑下面的索引定义:


CREATE INDEXcomp_ind 
ON table1(x, y, z);
  •   x,xy,xyz 都是索引的开头部分
  •   yz,y,z 都不是索引的开头部分

14.1.4.1 Choosing Keys forComposite Indexes 选择组合索引的列

创建组合索引时遵循如下原则:

  • 考虑在where子句中频繁一起出现的列,这些列用and 运算符连接作为条件,当它们组合在一起时选择性比它们任何一个单列作为索引都好的情况下使用组合索引。
  • 如果一些语句总是查询表中固定的几个列,可以考虑在这几个列上创建组合索引

当然,同时也要考虑索引带来的性能提升和索引造成的其他开销的平衡。


14.1.4.2 Ordering Keys forComposite Indexes  为组合索引的列排序

 排序时遵循如下原则:

  •  方便where子句使用索引的开头部分
  • 把最经常在where中出现的列放在最前面
  • 如果所有列的出现频率相同,但数据是按照某一列排序的,那么把这列放在索引的前面。

原文:

A composite index contains multiple key columns.Composite indexes can provide additional advantages over single-columnindexes:

  • Improved selectivity
    Sometimes you can combine two or more columns or expressions, each with poor selectivity, to form a composite index with higher selectivity.
  • Reduced I/O 
    If all columns selected by a query are in a composite index, then Oracle Database can return these values from the index without accessing the table.
     

A SQL statement can use an accesspath involving a composite index when the statement contains constructs thatuse a leading portion of the index.

Note:

This is no longer the case with index skipscans. See "Index Skip Scans".

A leading portion of an index is aset of one or more columns that were specified first and consecutively in thelist of columns in the CREATE INDEX statementthat created the index. Consider thisCREATE INDEX statement:

 

CREATE INDEXcomp_ind
ON table1(x, y, z);

  • x, xy, and xyz combinations of columns are leading portions of the index
  • yz, y, and z combinations of columns are not leading portions of the index 

14.1.4.1 Choosing Keys forComposite Indexes 

Follow these guidelines for choosing keys for compositeindexes:  

  • Consider creating a composite index on keys that appear together frequently in WHERE clause conditions combined with AND operators, especially if their combined selectivity is better than the selectivity of either key individually. 
  • If several queries select the same set of keys based on one or more key values, then consider creating a composite index containing all of these keys.

Of course, consider the guidelines associated with thegeneral performance advantages and trade-offs of indexes described in theprevious sections. 

14.1.4.2 Ordering Keys forComposite Indexes  

Follow these guidelines for ordering keys in compositeindexes:

  • Create the index so the keys used in WHERE clauses make up a leading portion.
  • If some keys appear in WHERE clauses more frequently, then create the index so that the more frequently selected keys make up a leading portion to allow the statements that use only these keys to use the index.
  • If all keys appear in WHERE clauses equally often but the data is physically ordered on one of the keys, then place this key first in the composite index.

14.1.5 Writing Statements That Use Indexes 编写用到索引的语句

即使创建了索引,优化器也不会单纯的由于索引存在就使用它。应该适当的编写sql语句使之可以用到索引。

原文:Even after you create an index, the optimizer cannotuse an access path that uses the index simply because the index exists. Theoptimizer can choose such an access path for a SQL statement only if itcontains a construct that makes the access path available. To allow the queryoptimizer the option of using an index access path, ensure that the statementcontains a construct that makes such an access path available.


14.1.6 Writing Statements That Avoid Using Indexes 编写不用索引的语句

在某些情况下,你不想语句用到以及存在的索引,比如你知道某个索引的选择性很差,用全表扫描会更高效。如果语句本身的结构会导致使用该索引,那你可以用以下方法强制优化器使用全表扫描:

  • 使用 NO_INDEX 提示,可以在不允许使用某索引的情况下给查询优化器更多的灵活性
  • 使用FULL提示让优化器进行全表扫描
  • 使用INDEX 或者 INDEX_COMBINE 提示让优化器使用指定的索引

并行执行有效的利用索引,它不进行并行索引范围扫描(index rangescans),但是在执行并行嵌套循环连接(parallel nested loop join)时它执行并行索引查找。当一个索引的选择性很高时(一个索引键值关联很少的行),还是用用连续索引查找比并行索引扫描好


原文:In some cases, you might want to prevent aSQL statement from using an access path that uses an existing index. You maywant to take this approach if you know that the index is not very selective and a full table scan wouldbe more efficient. If the statement contains a construct that makes such anindex access path available, then you can force the optimizer to use a fulltable scan through one of the following methods:

  • Use the NO_INDEX hint to give the query optimizer maximum flexibility while disallowing the use of a certain index.
  • Use the FULL hint to instruct the optimizer to choose a full table scan instead of an index scan. 
  • Use the INDEX or INDEX_COMBINE hints to instruct the optimizer to use one index or a set of listed indexes instead of another.
    See Also:
    Chapter 19, "Using Optimizer Hints" for more information on the NO_INDEXFULLINDEX, and INDEX_COMBINE and hints

Parallel execution uses indexeseffectively. It does not perform parallel index range scans, but it doesperform parallel index lookups for parallel nested loop join execution. If anindex is very selective (there are few rows for each index entry), then itmight be better to use sequential index lookup rather than parallel table scan.  


14.1.7 Re-creating Indexes 重建索引

有时候你可能想通过重建索引来压缩它所占用的空间和减少碎片空间,或者是想改变索引的存储属性。当你新创建的索引是某个已存在的索引的子集,或者是想重新创建一个已经存在的索引时,oracle会在已经存在的索引的基础上创建,而不是基于表创建,这样可以提高索引创建的性能。

但是,在某些情况下用原表比用已存在的索引要好。比如在一个表上进行了大量的DML操作,那么建立在这个表上的索引会膨胀到每个数据块中只有50%数据,甚至更少。如果这个index包含表中的大部分列的话,那么这个索引可能比原表更大。在这种情况下,还是基于原表重建索引会更好。

 使用 ALTER INDEX ... REBUILD语句可以重新组织索引,压缩索引,改变索引的存储属性。REBUILD语句使用已经存在的索引作为新建索引的基础。所有定义存储相关的子句都被支持,比如STORAGE (定义区分配 extent allocation,TABLESPACE (可以将索引移动到一个新的表空间)INITRANS (改变初始条目数)。

通常, ALTER INDEX ... REBUILD方式比删除索引重建要快,因为这个语句使用快速全扫描,它使用多块I/O(multiblock I/O)读取所有的索引块,然后丢弃分支块。这种方法还有一个好处就是当索引被重建时,原索引仍然有效。


原文:You might want to re-create an index to compact it and minimizefragmented space, or to change the index‘s storage characteristics. Whencreating a new index that is a subset of an existing index or when rebuildingan existing index with new storage characteristics, Oracle Database might usethe existing index instead of the base table to improve the performance of theindex build. 


However, in some cases using thebase table instead of the existing index is beneficial. Consider an index on atable on which a lot of DML has been performed. Because of the DML, the size ofthe index can increase to the point where each block is only 50% full, or evenless. If the index refers to most of the columns in the table, then the indexcould actually be larger than the table. In this case, it is faster to use thebase table rather than the index to re-create theindex.


Use the ALTER INDEX ... REBUILD statement to reorganize or compact an existing index orto change its storage characteristics. The REBUILD statement uses theexisting index as the basis for the new one. All index storage statements aresupported, such as STORAGE (for extent allocation), TABLESPACE (to move theindex to a new tablespace), and INITRANS (to change the initial number of entries).


Usually, ALTER INDEX ... REBUILD is faster than dropping and re-creating an index,because this statement uses the fast full scan feature. It reads all the indexblocks using multiblock I/O, then discards the branch blocks. A furtheradvantage of this approach is that the old index is still available for querieswhile the rebuild is in progress.  

See Also:

Oracle Database SQL Language Reference formore information about the CREATE INDEX and ALTER INDEX statements and restrictions onrebuilding indexes


14.1.8 Compacting Indexes 压缩索引

你可以使用ALTER INDEX 语句的COALESCE选项来合并索引的叶子节点。这个选项可以让你通过组合叶子节点来释放可重用的块空间。你也可以在线重建索引

原文:You can coalesce leaf blocks of anindex by using the ALTER INDEX statementwith the COALESCE option. This option lets you combine leaf levels of anindex to free blocks for reuse. You can also rebuild the index online. 

See Also:

OracleDatabase SQL Language Reference and OracleDatabase Administrator‘s Guide for more information about the syntax for thisstatement

14.1.9 Using Nonunique Indexes to EnforceUniqueness 使用非唯一索引实现唯一性

你可以使用已经存在的非唯一索引来实现唯一性,无论是对唯一约束或者是主键约束中的唯一约束部分。这种方式的好处是当你disable这些约束时,这些非唯一索引还保持有效,这样的话当你重新使这些约束生效时,不用重建和这些约束相关连的唯一索引。

使用非唯一索引来实现唯一性还可以使你减少索引的重复。如果主键列已经包含在一个组合索引中,而且在索引的最前面,你就不需要和这个主键关联的唯一索引了。减少索引的重复可以节省不少空间。不过,如果已经存在的索引被分区了,那么这个索引的分区key必须也是唯一key的子集,否则oracle会另外创建一个唯一索引来实现这个约束。


原文:You can use an existing nonuniqueindex on a table to enforce uniqueness,either for UNIQUE constraints or the unique aspect of a PRIMARY KEY constraint.The advantage of this approach is that the index remains available and validwhen the constraint is disabled. Therefore, enabling a disabled UNIQUE or PRIMARY KEY constraintdoes not require rebuilding the unique index associated with the constraint.This can yield significant time savings on enable operations for large tables. 

Using a nonunique index to enforce uniqueness also lets you eliminateredundant indexes. You do not need a unique index on a primary key column ifthat column is included as the prefix of a composite index. You can use theexisting index to enable and enforce the constraint. You also save significantspace by not duplicating the index. However, if the existing index ispartitioned, then the partitioning key of the index must also be a subset ofthe UNIQUE key;otherwise, Oracle Database creates an additional unique index to enforce theconstraint. 


14.1.10 Using Enabled Novalidated Constraints 使用EnabledNovalidated 约束

 对于新加入的数据,enabled novalidated 约束和enabledvalidated约束的行为是相似的。把一个约束置为enabled novalidated 状态意味着任何新加入的数据必须符合约束,但是并不检查已经存在的数据是否符合约束,这样的话enable这个约束不会锁表。

如果你把一个约束从disabled状态改为enable的话,表会被加锁。DML,查询,DDL操作都不能进行,因为在enable constraint 的操作进行时,没有办法保证这段时间的操作会符合约束。enablednovalidated 状态会阻止用户执行违反约束的操作。

 数据库可以使用一个并行、一致读查询来验证 enabled novalidated约束,来检查是否有数据违反约束。数据库执行该操作不加锁,所以不阻塞读写操作。另外数据库可以并行验证enabled novalidated 约束。数据库可以用并行查询来同时验证多个约束。

遵循如下方法来创建带有索引和约束的表:

  1. 在建表的时候创建约束。NOT NULL约束可以没有名字,它应该被创建为enabled validated状态。应该为索引其他的约束起名字(CHECK,UNIQUE,PRIMARY KEY  FOREIGN KEY),并且将它们创建为disabled状态。
  2. 将旧数据导入表中
  3. 创建所有的索引,包含约束需要的索引
  4. 将所有的索引置为ENABLED NOVALIDATED状态,先主键后外键。
  5. 允许用户查询和修改数据
  6. 针对每个约束,独立运行ALTER TABLE 语句来validate所有约束,先主键后外键。
比如:

CREATETABLE t (a NUMBER CONSTRAINT apk PRIMARY KEY DISABLE,
b NUMBER NOT NULL);
CREATE TABLE x (c NUMBER CONSTRAINT afk REFERENCES t DISABLE);

现在把数据导入到t表中

CREATE UNIQUE INDEXtai ON t (a); 
CREATE INDEX tci ON x (c); 
ALTER TABLE t MODIFY CONSTRAINT apk ENABLE NOVALIDATE;
ALTER TABLE x MODIFY CONSTRAINT afk ENABLE NOVALIDATE;

现在,用户可以在t表上进行增删改查操作了

ALTER TABLE t ENABLECONSTRAINT apk;
ALTER TABLE x ENABLE CONSTRAINT afk;


现在索引是处于enabled validated 状态了

原文:An enabled novalidated constraintbehaves similarly to an enabled validated constraint for new data. Placing aconstraint in the enabled novalidated state signifies that any new data enteredinto the table must conform to the constraint. Existing data is not checked. Byplacing a constraint in the enabled novalidated state, you enable theconstraint without locking the table.

If you change a constraint fromdisabled to enabled, then the table must be locked. No new DML, queries, or DDLcan occur, because no mechanism can ensure that operations on the table conformto the constraint during the enable operation. The enabled novalidated stateprevents users from performing operations on the table that violate theconstraint.

 

The database can validate anenabled novalidated constraint with a parallel, consistent-read query of thetable to determine whether any data violates the constraint. The databaseperforms no locking, so the enable operation does not block readers or writers.In addition, the database can validate enabled novalidated constraints inparallel. The database can validate multiple constraints at the same time andcheck the validity of each constraint using parallel query.

Use the following approach tocreate tables with constraints and indexes: 

  1. Create the tables with the constraints. NOT NULL constraints can be unnamed and should be created enabled and validated. You should name all other constraints (CHECKUNIQUE,PRIMARY KEY, and FOREIGN KEY) and create them disabled.
  1. Load old data into the tables. 
  2. Create all indexes, including indexes needed for constraints.
  3. Enable novalidate all constraints. Do this to primary keys before foreign keys. 
  4. Allow users to query and modify data.
  5. With a separate ALTER TABLE statement for each constraint, validate all constraints. Do this to primary keys before foreign keys. 

 

 

 For example,
CREATETABLE t (a NUMBER CONSTRAINT apk PRIMARY KEY DISABLE,
b NUMBER NOT NULL);
CREATE TABLE x (c NUMBER CONSTRAINT afk REFERENCES t DISABLE);

 

 

Now load data into table t.

CREATE UNIQUE INDEXtai ON t (a);
CREATE INDEX tci ON x (c);
ALTER TABLE t MODIFY CONSTRAINT apk ENABLE NOVALIDATE;
ALTER TABLE x MODIFY CONSTRAINT afk ENABLE NOVALIDATE;

 

At this point, users can startperforming INSERTUPDATEDELETE, and SELECT operations ontable t.

ALTER TABLE t ENABLECONSTRAINT apk;
ALTER TABLE x ENABLE CONSTRAINT afk;

 

Now the constraints are enabled and validated.

See Also:

OracleDatabase Concepts for a complete discussion of integrityconstraints



 




14.1 Understanding Index Performance 了解索引性能

标签:性能

原文地址:http://blog.csdn.net/adeline_pan/article/details/47340805

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!