`

索引与Null值对于Hints及执行计划的影响

 
阅读更多

由于B*Tree索引不存储Null值,所以在索引字段允许为空的情况下,某些Oracle查询不会使用索引.

很多时候,我们看似可以使用全索引扫描(Full Index Scan)的情况,可能Oracle就会因为Null值的存在而放弃索引.

在此情况下即使使用Hints,Oracle也不会使用索引,其根本原因就是因为Null值的存在.

我们看以下测试.

username字段为Not Null时,Index Hints可以生效.

SQL> create table t as select username,password from dba_users;
Table created.
SQL> desc t
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 USERNAME                                  NOT NULL VARCHAR2(30)
 PASSWORD                                           VARCHAR2(30)
SQL> create index i_t on t(username);
Index created.
SQL> set autotrace trace explain
SQL> select * from t where username='EYGLE';
Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |    34 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T    |     1 |    34 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("USERNAME"='EYGLE')
Note
-----
   - dynamic sampling used for this statement
SQL> set linesize 120
SQL> select /*+ index(t,i_t) */ * from t where username='EYGLE';
Execution Plan
----------------------------------------------------------
Plan hash value: 2928007915
------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |     1 |    34 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T    |     1 |    34 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | I_T  |     1 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("USERNAME"='EYGLE')
Note
-----
   - dynamic sampling used for this statement

当索引字段允许为Null时,Oracle放弃此索引:

SQL> alter table t modify (username null);
Table altered.
SQL> select /*+ index(t,i_t) */ * from t;
Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    27 |   918 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| T    |    27 |   918 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement 

当该字段为Not Null时,索引可以被强制使用:

SQL> alter table t modify (username not null);
Table altered.
SQL> select /*+ index(t,i_t) */ * from t;
Execution Plan
----------------------------------------------------------
Plan hash value: 3593393735
------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |    27 |   918 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T    |    27 |   918 |     2   (0)| 00:00:01 |
|   2 |   INDEX FULL SCAN           | I_T  |    27 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement
 

这就是Null值对于索引及查询的影响.

分享到:
评论

相关推荐

    Oracle数据库关于SQL的执行计划

    ### Oracle数据库关于SQL的执行计划 #### 1. Oracle 的 Optimizer 及其相关知识 在 Oracle 数据库中,执行 SQL 查询之前会先生成一个执行计划(Execution Plan),该计划由 Oracle 的优化器(Optimizer)根据一...

    SQLServer索引设计和调优技巧大全.pdf

    - **稀疏索引**:对于含有大量NULL值的列,稀疏索引可以节省存储空间。 - **非聚集覆盖索引**:这种索引不包含表的所有列,但包含查询所需的特定列,可以减少I/O操作。 7. **索引维护和调优**: - 定期执行索引...

    ORACLE SQL语句执行效率研究.pdf

    优化过程通常包括定位性能差的语句、检查执行计划、分析统计信息、检查记录数和索引情况等步骤。作者强调,SQL调优是一个系统工程,需要全面考虑SQL的结构和数据库的工作原理。 在提高查询效率方面,文章提出了利用...

    《Pro Oracle SQL》 10.2.4 Seizing Other Optimization Opportunities

    NULL值在数据库中的处理方式与非NULL值不同,它们可能导致不必要的计算和效率降低。在实际的SQL语句中,我们需要注意如何正确地使用NULL值,避免在条件判断中产生误判或者增加计算负担。例如,使用`IS NULL`或`IS ...

    SQL优化公开课1

    使用SQL提示(Hints)来指导优化器使用特定的执行计划。 2. 创建SQL Profile来存储优化过的执行计划,确保每次查询都使用相同的计划。 3. 利用SQL Plan Management(SPM)特性来管理执行计划版本。 #### 十、...

    SQL优化 '%5400%' LIKE操作符

    4. **Oracle Hints的使用**:虽然可以直接控制执行计划,但需谨慎使用,并定期评估其对系统性能的影响。 综上所述,SQL优化是一项复杂而细致的工作,需要结合实际应用场景灵活运用各种技术和方法。只有不断实践与...

    sql性能的调整-总结

    - **使用hints**:通过在SQL语句中添加注释形式的hints,可以直接控制执行计划的选择。 #### 七、具体案例分析 通过对实际场景中的SQL查询进行案例分析,可以帮助我们更好地理解和实践SQL性能调整的技术和方法。 ...

    oracle sql性能调优

    9. **查询优化器HINTs**:在SQL语句中使用HINTs可以强制优化器使用特定的执行计划,但这需要谨慎使用,避免过度依赖。 10. **数据库架构优化**:合理设计表分区,根据业务特点选择合适的分区策略,如范围分区、列表...

    oracle数据库期末考试试题及答案(一).pdf

    - 绑定变量用于减少解析开销,提高性能,但可能影响执行计划的选择。 13. **索引查询的性能**: - 不总是能提高查询性能,如果查询条件不符合索引,或数据分布不均,可能反而降低性能。 14. **性能指标**: - ...

    Oracle内部培训汇总

    1. **优化器**:Oracle的查询优化器是数据库性能的关键组件,它负责选择最优的执行计划。优化器有两种主要类型:基于规则的优化器(RBO)和基于成本的优化器(CBO)。从Oracle 9i版本开始,CBO逐渐成为默认选择,...

    Oracle SQL的优化.txt

    3. **使用 IS NULL 和 IS NOT NULL**:对于NULL值的查询,建议使用 `IS NULL` 和 `IS NOT NULL` 操作符,而不是使用 `= NULL` 或 `<> NULL`,因为后者会导致全表扫描。 4. **NOT IN 和 EXISTS 的使用**:在进行子...

    Oracle Sql 优化

    在WHERE子句中使用`IS NULL`或`IS NOT NULL`会导致Oracle优化器无法利用索引进行优化,因为NULL值并不参与索引排序。为了充分利用索引,应避免在WHERE子句中使用这类条件,除非确实需要检查NULL值的存在。 ##### ...

    ORACLE SQL性能調整

    在SQL语句中使用Hints可以指导优化器选择特定的执行计划,这对于复杂的查询特别有用。 #### 31. 用WHERE替代ORDER BY 在某些场景下,使用WHERE子句过滤数据后再进行ORDER BY操作可以减少排序的工作量,从而提高...

    Oracle语句优化53个规则详解.rar

    22. **避免在索引列上使用NULL值**:NULL值在索引中处理特殊,可能影响性能。 23. **使用索引合并策略**:当有多个可能的索引时,Oracle会尝试合并它们。 24. **注意行链接顺序**:JOIN操作中,先链接小表可以提高...

    oracle数据库期末考试试题与答案一.doc

    【知识点详解】 1. Oracle数据库查询优化:Oracle数据库在执行SQL查询时,会根据...6. 稳定执行计划:通过绑定变量、使用SQL profile或SQL plan baseline来固定执行计划,避免因统计信息变化导致的执行计划不稳定。

    oracle数据库期末考试试题及答案(一).doc

    2. 查询优化器关注的主要是执行计划的选择,以及如何减少I/O操作、优化索引使用、合理利用缓存等。 3. 查看执行计划可通过EXPLAIN PLAN或设置SQL_TRACE,查看执行计划的详细信息。 4. 索引对写操作有负面影响,...

    sql语句优化之降龙十八掌

    定期更新表的统计信息,确保优化器能够做出准确的执行计划,避免过度或不足的索引使用。 通过以上十八掌,你可以对SQL语句进行深度优化,实现数据库性能的最大化。但请记住,每个数据库系统都有其特性和最佳实践,...

    数据库性能优化 心得体会 笔记

    - **建议**:在必要时合理使用HINTs来优化执行计划。 12. **DISTINCT与GROUP BY的使用** - `DISTINCT`关键字用于返回唯一不同的值。 - `GROUP BY`用于对数据进行分组。 - 在某些情况下,`GROUP BY`可以作为`...

    ORACLE+SQL性能调整

    20. **使用 TKPROF 工具**:通过 TKPROF 分析 SQL 执行计划,找出性能瓶颈。 21. **用 EXPLAIN PLAN 分析 SQL 语句**:EXPLAIN PLAN 可以显示 Oracle 选择的执行路径,帮助优化查询。 22. **使用索引提高效率**:...

    Getting The Best From The Cost Based Optimizer

    - 调整`OPTIMIZER_USE_PLSQL_FUNCTION_HINTS`参数,让CBO能够利用函数提示来优化执行计划。 #### 4. 约束条件 约束条件对于CBO的决策非常重要,它们可以提供关于表结构的重要信息,帮助优化器做出更好的选择。例如...

Global site tag (gtag.js) - Google Analytics