`

hint指定index的深入理解

 
阅读更多

创建一个表,含有位图index和b-tree index

SQL> create table t as select object_id id ,object_name from dba_objects;
Table created.
SQL> create index b_tree_ind on t(id);
Index created.

SQL> create bitmap index b_bm_name on t(object_name);
Index created.

SQL> exec dbms_stats.gather_table_stats('HR','T',cascade=> true);
SELE
PL/SQL procedure successfully completed.

SQL> set autotrace trace exp stat

SQL> select id from t;
50365 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      | 47448 |   602K|    57   (2)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| T    | 47448 |   602K|    57   (2)| 00:00:01 |
--------------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement
Statistics
----------------------------------------------------------
         28  recursive calls
          0  db block gets
       3646  consistent gets
          0  physical reads
          0  redo size
     728900  bytes sent via SQL*Net to client
      37312  bytes received via SQL*Net from client
       3359  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      50365  rows processed

这里因为object_id列可能有null值,所以不会使用b_tree_t_xifenfei索引,预料之中事件

SQL> select /*+ index(t b_tree_ind) */ id from t
50365 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3465251059
------------------------------------------------------------------------------------------
| Id  | Operation                    | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |           | 47448 |   602K|   805   (1)| 00:00:10 |
|   1 |  TABLE ACCESS BY INDEX ROWID | T         | 47448 |   602K|   805   (1)| 00:00:10 |
|   2 |   BITMAP CONVERSION TO ROWIDS|           |       |       |            |          |
|   3 |    BITMAP INDEX FULL SCAN    | B_BM_NAME |       |       |            |          |
------------------------------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
      27318  consistent gets
          0  physical reads
          0  redo size
    2147500  bytes sent via SQL*Net to client
      37312  bytes received via SQL*Net from client
       3359  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      50365  rows processed

这里因为object_id列可能有null值,所以不会使用b_tree_t_xifenfei索引,这里的疑惑是:
就算不会使用b_tree_t_xifenfei index也不应该会使用BITMAP_T_XIFENFEI index,因为使用这个的cost会大于全表扫描

SQL> select /*+ index(t aaa) */ id from t;
50365 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3465251059
------------------------------------------------------------------------------------------
| Id  | Operation                    | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |           | 50365 |   245K|   805   (1)| 00:00:10 |
|   1 |  TABLE ACCESS BY INDEX ROWID | T         | 50365 |   245K|   805   (1)| 00:00:10 |
|   2 |   BITMAP CONVERSION TO ROWIDS|           |       |       |            |          |
|   3 |    BITMAP INDEX FULL SCAN    | B_BM_NAME |       |       |            |          |
------------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
      27318  consistent gets
          0  physical reads
          0  redo size
    2147500  bytes sent via SQL*Net to client
      37312  bytes received via SQL*Net from client
       3359  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
      50365  rows processed

这里使用了一个无效的index,也使用了BITMAP_T_XIFENFEI,让人更加的感觉奇怪。
官方文档上有如下解释
If the INDEX hint specifies a single available index, then the database performs a scan on this index. The optimizer does not consider a full table scan or a scan of another index on the table.
For a hint on a combination of multiple indexes, Oracle recommends using INDEX_COMBINE rather than INDEX, because it is a more versatile hint. If the INDEX hint specifies a list of available indexes, then the optimizer considers the cost of a scan on each index in the list and then performs the index scan with the lowest cost. The database can also choose to scan multiple indexes from this list and merge the results, if such an access path has the lowest cost. The database does not consider a full table scan or a scan on an index not listed in the hint.
If the INDEX hint specifies no indexes, then the optimizer considers the cost of a scan on each available index on the table and then performs the index scan with the lowest cost. The database can also choose to scan multiple indexes and merge the results, if such an access path has the lowest cost. The optimizer does not consider a full table scan.
如果我们使用hint指定了一个无效的index,优化器会扫描表中所有可以使用的index,然后选择cost最小的index或者index组合,而不会选择全表扫描。
因为我们hint指定b_tree_t_xifenfei index的时候,因为object_id可能有值为空(列没定义为not null),所以不能使用该index,从而也就是相当于一个无效的index,从而扫描该表的其他可以使用的index,导致使用了位图索引(该类型index不排除null),而不是全表扫描.在9i和10g上有上述现象,11g时Oracle对上述现象有所改进
注意:使用hint指定index的时候需要慎重,如果不合适或者无效,可能导致程序效率更低


感谢惜分飞的指点

参考至:http://www.xifenfei.com/2865.html

如有错误,欢迎指正

邮箱:czmcj@163.com

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Oracle 中HINT的使用

    Oracle中的HINT是一种非常强大的工具,它允许数据库管理员和开发人员通过在SQL语句中...然而,正确使用HINT需要深入理解SQL语句的执行过程和数据库的工作原理,同时也需要注意避免过度依赖,保持查询的灵活性和适应性。

    小菜鸟系列-Oracle的优化器与hint

    通过深入理解Oracle的优化器和hint,开发者和DBA可以更好地优化数据库性能,提升系统的整体运行效率。这不仅有助于提高数据查询速度,还能减少服务器资源的消耗,从而节省成本。在日常工作中,不断学习和掌握这些...

    oracle_hint教程汇总

    Oracle Hint是Oracle数据库系统中的一种特性,它允许数据库管理员或开发人员通过在SQL语句中...在"Oracle Hint.doc"和"Oracle_Hint使用实例.pdf"中,你可以找到更具体的示例和深入的解释,以帮助理解和掌握这些技巧。

    oracle CBO HINT

    Oracle的Cost-Based Optimizer (CBO) 是一种自动选择最优执行计划的机制,它通过评估不同执行路径的成本来决定...然而,由于CBO的复杂性,深入理解和实践是至关重要的。务必在生产环境中谨慎应用,以防止可能的反效果。

    Oracle Hint的用法

    ### Oracle Hint 的深入解析与应用 #### 一、概述 Oracle Hint是一种用于指导Oracle数据库优化器如何执行查询的特殊语法。通过使用特定的Hint,开发人员可以显式地告诉优化器采用哪种策略来处理SQL语句,从而实现...

    using pl/sql hint

    这些提示的使用需要深入理解查询的具体需求以及数据库中数据的分布情况。在实际应用中,合理利用这些提示可以极大地提升SQL查询的性能,尤其是在处理大型数据库和复杂查询时。然而,过度依赖提示可能会限制优化器的...

    ORACLE中的的HINT详解

    本文将深入探讨Oracle HINT的使用和功能。 1. **HINT的基本概念** HINT是Oracle提供的一种特殊指令,它们被插入到SQL语句中,用于指导查询优化器选择特定的执行策略。优化器是Oracle处理查询时的一个组件,它的...

    Oracle 语句优化

    在使用这些Hint时,需要有对Oracle数据库结构、数据分布和查询模式的深入了解,以便正确地指导优化器选择最合适的执行计划。不过,值得注意的是,随着Oracle版本的更新,自动的SQL优化功能已越来越强大,因此在使用...

    Hints优化.pdf

    在实际操作中,合理利用Oracle Hints进行数据库查询优化是一个技术性很强的工作,需要深入理解SQL语言、数据库的工作原理以及Oracle优化器的工作机制。在对数据库进行性能优化时,应该遵循Oracle官方文档的指导,并...

    汇编程序,复制自身到指定地址

    在80x86汇编语言中,编程者可以创建自复制程序,即程序能够将自身的代码复制到内存中的另一个位置。这样的程序通常用于病毒、恶意软件或教学...这样的技术对于深入理解操作系统、内存管理和底层编程原理非常有帮助。

    Memo控件的使用方法和详解

    2. `Delete(index: integer)`: 删除指定索引的字符串。 3. `Insert(index: integer; const s: string)`: 在指定位置插入一个字符串。 4. `Clear()`: 清除所有字符串,使`Lines`为空。 5. `LoadFromFile(const ...

    Oracle SQL 优化与调优技术详解-附录:SQL提示

    为了能够合理使用这些提示,DBA需要深入理解Oracle优化器的工作原理以及表和索引的存储结构。合理利用提示,可以在特定情况下优化性能,但也需注意,不当的使用提示可能会产生性能问题,甚至导致数据不一致。 这里...

    javaee 优化器

    ### JavaEE 优化器:深入理解 Oracle Optimizer 在JavaEE开发中,为了提升应用程序的性能,往往需要对数据库查询进行优化。Oracle Optimizer作为Oracle数据库的重要组成部分,在选择执行计划时发挥着关键作用。本文...

    oracle 性能调优

    例如,`/*+ INDEX(table index_name) */` 可以强制使用指定的索引。 5. **COST**:在优化器中,COST是衡量执行计划代价的指标,包括CPU时间、I/O操作、内存使用等。优化器会选择总成本最低的执行计划。 性能调优不...

    sql性能的调整

    ### SQL性能调整关键知识点 ...通过对SQL性能调整的关键知识点的深入了解,我们可以更有效地管理和优化数据库系统的性能。这不仅有助于提升应用程序的响应速度,还能确保资源的有效利用,最终实现业务目标。

    mongoose-partial-full-search-源码.rar

    深入理解这部分源码,对于想要在mongoose上构建高效全文搜索功能的开发者来说,将是一份宝贵的资源。它揭示了如何在保持性能的同时,根据具体需求定制全文搜索行为,对于提升应用的用户体验有着显著的帮助。

    oracle索引介绍

    通过提示(Hint)可以强制指定优化器的行为。 2. **示例演示**: 为了解释上述理论知识,我们可以参考以下实例: - **创建索引**: ```sql SQL> create index indx_t on t(object_type, object_name); ``` ...

    Oracle语句优化规则详解【技术文档】

    通过FROM子句中的表顺序或使用 hint(/*+ ORDERED */)可以指定连接顺序。 3. 使用连接条件:确保连接条件在索引上,以利用索引加速连接。 四、子查询优化 1. 使用 EXISTS 替代 IN:当子查询只关心是否存在匹配记录...

    oracle 索引不能使用深入解析

    并行查询通常不使用索引,如果需要使用特定索引,可以通过SQL提示(hint)来指定,如`SELECT /*+ INDEX(A IND_COL1) */ * FROM A WHERE COL1 = XXX;`。 最后,利用EXPLAIN PLAN功能可以帮助理解查询的执行计划。...

    mongodb优化

    6. 强制使用索引:通过 `hint` 指定查询应使用的索引。 7. 性能分析(profiling):通过调整 `profilingLevel` 监控不同级别的查询性能,根据分析结果进行优化。 在 MongoDB 中,`COLLSCAN` 表示全集合扫描,这意味...

Global site tag (gtag.js) - Google Analytics