`
JohnnyCan
  • 浏览: 28626 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Oracle索引分析与比较(2)

阅读更多

 

26.5  附表(索引什么时候不工作)

首先要声明两个知识点:

1RBO&CBO

Oracle有两种执行优化器,一种是RBO(Rule Based Optimizer)基于规则的优化器,这种优化器是基于sql语句写法选择执行路径的;另一种是CBOCost Based Optimizer)基于规则的优化器,这种优化器是Oracle根据统计分析信息来选择执行路径,如果表和索引没有进行分析,Oracle将会使用RBO代替CBO;如果表和索引很久未分析,CBO也有可能选择错误执行路径,不过CBOOracle发展的方向,自8i版本来已经逐渐取代RBO.

2AUTOTRACE

要看索引是否被使用我们要借助Oracle的一个叫做AUTOTRACE功能,它显示了sql语句的执行路径,我们能看到Oracle内部是怎么执行sql的,这是一个非常好的辅助工具,在sql调优里广泛被运用。我们来看一下怎么运用AUTOTRACE

由于AUTOTRACE自动为用户指定了Execution Plan,因此该用户使用AUTOTRACE前必须已经建立了PLAN_TABLE。如果没有的话,请运行utlxplan.sql脚本(它在$ORACLE_HOME/rdbms/admin目录中)。

AUTOTRACE可以通过运行plustrce.sql脚本(它在$ORACLE_HOME/sqlplus/admin目录中)来设置,用sys用户登陆然后运行plustrce.sql后会建立一个PLUSTRACE角色,然后给相关用户授予PLUSTRACE角色,然后这些用户就可以使用AUTOTRACE功能了。

AUTOTRACE的默认使用方法是set autotrace on,但是这方法不总是适合各种场合,特别当返回行数很多的时候。Set autotrace traceonly提供了只查看统计信息而不查询数据的功能。

    SQL> set autotrace on

SQL> select * from test;

         A

----------

         1

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=CHOOSE

   1    0   TABLE ACCESS (FULL) OF 'TEST'

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

          0  consistent gets

          0  physical reads

          0  redo size

          0  bytes sent via SQL*Net to client

          0  bytes received via SQL*Net from client

          0  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

rows processed

 

SQL> set autotrace traceonly

SQL> select * from test.test;

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=CHOOSE

   1    0   TABLE ACCESS (FULL) OF 'TEST'

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

          0  consistent gets

          0  physical reads

          0  redo size

          0  bytes sent via SQL*Net to client

          0  bytes received via SQL*Net from client

          0  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

rows processed

HintsOracle提供的一个辅助用法,按字面理解就是'提示'的意思,确实它起得作用也是提示优化器按它所提供的关键字来选择执行路径,特别适用于sql调整的时候。使用方法如下:

{DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */

具体可参考Oracle SQL Reference

有了前面这些知识点,接下来让我们来看一下什么时候索引是不起作用的。以下列出几种情况。

 

1)类型不匹配时。

SQL> create table test.testindex (a varchar(2),b number);

表已创建。

SQL> create index ind_cola on test.testindex(a);

索引已创建。

SQL> insert into test.testindex values('1',1);

已创建 1 行。

SQL> commit;

提交完成。

SQL> analyze table test.testindex compute statistics for all indexes;

表已分析。

SQL> set autotrace on;

SQL> select /*+RULE */* FROM test.testindex where a='1';(使用基于rule的优化器,数据类型匹配的情况下)

A           B

-- ----------

1           1

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=HINT: RULE

   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'TESTINDEX'

   2    1     INDEX (RANGE SCAN) OF 'IND_COLA' (NON-UNIQUE)(使用了索引ind_cola

――――――――――――――――――――――――――――――――――

SQL> select /*+RULE */* FROM test.testindex where a=1;(数据类型不匹配的情况)

A           B

-- ----------

1           1

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=HINT: RULE

   1    0   TABLE ACCESS (FULL) OF 'TESTINDEX'(优化器选择了全表扫描)

 

2)条件列包含函数但没有创建函数索引。

SQL> select /*+ RULE */*  FROM test.testindex where upper(a)= 'A';(使用了函数upper()在列a上);

A           B

-- ----------

a           2

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=HINT: RULE

   1    0   TABLE ACCESS (FULL) OF 'TESTINDEX'(优化器选择全表扫描)

----------------------------------------------------------

创建基于函数的索引

SQL> create index test.ind_fun on test.testindex(upper(a));

索引已创建。

SQL> insert into testindex values('a',2);

已创建1行。

SQL> commit;

提交完成。

SQL> select /*+ RULE*/*  FROM test.testindex where upper(a)='A';

A           B

-- ----------

a           2

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=HINT: RULE

   1    0   TABLE ACCESS (FULL) OF 'TESTINDEX'

(RULE优化器下忽略了函数索引选择了全表扫描)

-----------------------------------------------------------

SQL> select *  FROM test.testindex where upper(a)

='A';

A           B

-- ----------

a           2

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=5)

   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'TESTINDEX' (Cost=2 Card=

          1 Bytes=5)

   2    1     INDEX (RANGE SCAN) OF 'IND_FUN' (NON-UNIQUE) (Cost=1 Car

          d=1)(CBO优化器使用了ind_fun索引)

 

3)复合索引中的前导列没有被作为查询条件。

创建一个复合索引

SQL> create index ind_com on test.testindex(a,b);

索引已创建。

SQL> select /*+ RULE*/* from test.testindex where a='1';

A           B

-- ----------

1           2

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=HINT: RULE

   1    0   INDEX (RANGE SCAN) OF 'IND_COM' (NON-UNIQUE)(条件列表包含前导列时使用索引ind_com)

SQL> select /*+ RULE*/* from test.testindex where b=1;

未选定行

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=HINT: RULE

   1    0   TABLE ACCESS (FULL) OF 'TESTINDEX'(条件列表不包括前导列是选择全表扫描)

-----------------------------------------------------------

 

4CBO模式下选择的行数比例过大,优化器采取了全表扫描。

SQL> select * from test.testindex where a='1';

A           B

-- ----------

1           2

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=5)

   1    0   TABLE ACCESS (FULL) OF 'TESTINDEX' (Cost=1 Card=1 Bytes=5)

(表一共2行,选择比例为50%,所以优化器选择了全表扫描)

――――――――――――――――――――――――――――――――――

下面增加表行数

SQL> declare i number;

  2  begin

  3  for i in 1 .. 100 loop

  4  insert into test.testindex values (to_char(i),i);

  5  end loop;

  6  end;

  7  /

PL/SQL 过程已成功完成。

SQL> commit;

提交完成。

SQL> select count(*) from test.testindex;

  COUNT(*)

----------

102

SQL> select * from test.testindex where a='1';

A             B

---- ----------

1             1

1             2

Execution Plan

SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=5)

1    0   INDEX (RANGE SCAN) OF 'IND_COM' (NON-UNIQUE) (Cost=1 Card=1 Bytes=5)

(表一共102行,选择比例为2/102=2%,所以优化器选择了索引扫描)

 

分享到:
评论

相关推荐

    Oracle索引分析与比较

    Oracle 索引是数据库管理系统中提升数据查询速度的关键组件,尤其在大型企业级应用中,选择合适的索引类型对于数据库性能至关重要。本篇文章将深入探讨Oracle中的B*Tree索引、反向索引、降序索引、位图索引和函数...

    oracle索引分析与比较

    Oracle数据库中的索引是提升数据查询效率的关键工具,主要包括B*Tree索引、反向索引、降序索引、位图索引和函数索引五种类型。每种索引都有其特定的适用场景和优缺点。 1. **B*Tree索引**:B*Tree(B树)是最常见和...

    Oracle索引分析与查询优化.pdf

    Oracle 索引分析与查询优化 Oracle 是一种关系型数据库,广泛应用于国内交通、电力、通信和金融等重要领域。 Oracle 在处理数据效率和数据安全上有非常大的提高,磁盘阵列技术(RAID)和集群技术(RAC)的运用也...

    Oracle索引机制分析

    总的来说,Oracle索引机制的深入理解对于数据库性能调优、查询优化和系统设计都具有重要意义。正确使用索引可以显著提高查询速度,降低响应时间,提升用户体验,但同时也需要平衡索引对写操作的影响,以确保系统的...

    oracle索引机制分析

    ### Oracle索引机制分析 #### 1. 基本索引概念 索引是数据库管理系统(DBMS)为了加快数据检索速度而采用的一种数据结构。Oracle提供了多种类型的索引,每种索引都有其特定的优势和适用场景。索引的基本目的是通过...

    oracle约束和索引笔记

    - **唯一索引(Unique Index)**: 确保索引键的唯一性,与唯一约束相似,但不强制非空。 - **分区索引(Partitioned Index)**: 将大型表的索引分割成更小、更易管理的部分,提高大规模数据的查询性能。 - **复合...

    ORACLE索引详解及SQL优化

    本文将深入探讨Oracle索引的原理、创建方法,并结合SQL优化策略,帮助你提升数据库查询速度,降低资源消耗。 首先,我们要理解索引的基本概念。在数据库中,索引类似于书籍的目录,它为数据提供快速访问的途径。...

    oracle索引,常见索引问题

    Oracle数据库中的索引是优化查询性能的关键工具,它允许快速定位和访问数据。常见的索引类型包括B*树索引和位图索引,每种都有其特定的应用场景和优势。 1. **B*树索引**:这是最常见的索引类型,类似于二叉树结构...

    数据库 创建索引 sql oracle

    "数据库创建索引SQL Oracle" 数据库索引是数据库性能优化的重要手段之一。创建索引可以提高查询速度,降低数据库的负载,提高数据的安全性。本文将详细介绍数据库创建索引的原则、分类、创建方法、管理和优化等方面...

    oracle索引分析说明

    本文将深入探讨Oracle索引的使用、存储原理以及如何分析索引效率,特别是通过`clustering_factor`这个指标来评估索引的性能。 首先,让我们理解索引的工作原理。在Oracle中,索引是一种特殊的数据库对象,它为表的...

    09 oracle的索引 PPT

    3. 使用EXPLAIN PLAN分析查询:Oracle的EXPLAIN PLAN功能可以帮助分析查询计划,了解是否使用了索引以及其效果。 四、索引的管理 1. 创建索引:使用CREATE INDEX语句创建新索引。 2. 监控性能:通过V$视图如V$INDEX...

    Oracle 索引练习语句程序

    ### Oracle索引的基本概念 #### 1. 创建索引 索引是数据库中一种用于提高数据检索速度的数据结构。通过创建索引,可以显著提升查询性能。例如,在`student`表上创建一个基于`sno`列的索引: ```sql CREATE INDEX ...

    oracle索引类型及扫描方式大整理new

    ### Oracle索引类型详解 #### 一、B\*Tree索引:数据检索的基石 在Oracle数据库中,B\*Tree索引是最常见的索引结构,也是默认创建的索引类型。它基于二叉树原理,由分支块(branch block)和叶块(leaf block)构成,...

    oracle分区与索引

    ### Oracle 分区与索引详解 #### 一、Oracle 分区概述 在Oracle数据库中,分区是一种物理数据组织技术,它将一个大的表或索引分成多个较小的部分,每个部分都可以独立管理。通过分区,可以显著提高查询性能,简化...

    Oracle数据库索引的维护

    在Oracle数据库管理与优化的过程中,索引的维护是非常关键的一环。合理地创建、管理和优化索引能够显著提高查询性能,降低系统的响应时间,从而提升整个应用程序的效率。本文将从Oracle数据库索引的基础概念出发,...

    Oracle 索引

    Oracle索引是数据库管理系统中用于加速数据检索的关键结构。它们的工作原理类似于书籍的目录,允许数据库系统快速定位和访问特定的数据行,而无需扫描整个表。Oracle提供了多种类型的索引,包括B树索引、位图索引、...

    oracle不走索引可能原因.docx

    例如,一个字符类型的列与整数进行比较时,会导致Oracle不使用索引。这种情况下,可以避免类型转换,或者确保比较的两边数据类型一致,以利用索引。 5. **数据量比例**: 如果查询返回的记录数量占表总记录的较大...

    oracle索引类型及扫描方式大整理

    3. **位图索引**:主要用于OLAP(在线分析处理)系统,当查询涉及多列或低基数数据列时,位图索引可以将多个行映射到一个位,节省存储空间,但在大量插入和删除操作时效率较低。 4. **函数索引**:索引基于列的特定...

    oracle的索引学习

    本篇文章将深入探讨Oracle索引的学习,重点关注索引的原理、类型、优缺点以及如何使用和分析执行计划。 首先,理解索引的基本概念。索引是一种特殊的数据结构,它存储在表空间中,用于加速对表数据的访问。当执行...

Global site tag (gtag.js) - Google Analytics