oracle不走索引

1. 引言

在关系型数据库中,对于大表、复杂查询,优化查询速度常常需要使用索引。索引是一种排序的数据结构,可以提高查询效率。而在Oracle数据库中,即便建立了索引,查询仍有可能不走索引。本文将探讨Oracle中不走索引的情况,以及如何避免这种情况。

2. 何时会不走索引

2.1 非等值条件下的查询

当查询条件中包含不等值比较符(如>、<、>=、<=、<>, !=等),Oracle会基于cost选择最优执行计划,有可能不走索引。例如,以下查询语句:

SELECT * FROM employees WHERE salary > 5000;

即便在salary字段上建立了索引,Oracle有可能会选择全表扫描来处理这个查询。

2.2 NULL值查询

当查询条件中包含NULL值条件时,索引并不会被使用。例如,以下查询语句:

SELECT * FROM employees WHERE commission_pct IS NULL;

即便在commission_pct字段上建立了索引,Oracle也不会使用该索引。

2.3 多列索引的顺序问题

在Oracle数据库中,可以建立多列索引。对于多列索引,查询条件不符合索引第一列时,索引可能不会被使用。例如,以下查询语句:

SELECT * FROM employees WHERE department_id=10 AND salary > 5000;

如果在(department_id, salary)上建立了索引,并且department_id是索引的第二列,那么Oracle可能不会使用该索引。

3. 如何避免不走索引

3.1 正确使用索引

在建立索引时,需要根据业务需求正确选择索引的列和类型。

当查询包含不等值条件时,可以考虑建立位图索引。位图索引适用于相对静态的表,其中列的值有相对较少的修改,查询包含大量等于操作和少量不等于操作的场景。例如,以下查询语句:

SELECT * FROM employees WHERE salary > 5000;

可以建立位图索引:

CREATE BITMAP INDEX employees_salary_index ON employees(salary);

3.2 优化SQL语句

在编写SQL查询时,可以通过多种方式优化语句,从而避免不走索引的情况:

3.2.1 避免使用变量或函数包装列名

当SQL语句中的列名被包装在变量或函数中时,会导致Oracle不走索引。例如,以下查询语句:

DECLARE

salary employees.salary%TYPE;

BEGIN

SELECT AVG(salary) INTO salary FROM employees;

END;

这种SQL语句的执行计划中不会使用employees表上的任何索引。

相应地,可以将列名直接写在SQL语句中,避免使用变量或函数包装列名。

3.2.2 避免使用NOT关键字

当SQL语句中包含NOT关键字时,索引不一定会被使用。例如,以下查询语句:

SELECT * FROM employees WHERE salary < 5000 AND commission_pct IS NOT NULL;

可以通过改写为等价的SQL语句来避免NOT关键字:

SELECT * FROM employees WHERE salary < 5000 AND commission_pct > 0;

3.2.3 避免使用OR关键字

当SQL语句中包含OR关键字时,索引也不一定会被使用。例如,以下查询语句:

SELECT * FROM employees WHERE salary < 5000 OR commission_pct IS NOT NULL;

可以通过将OR改写为UNION ALL来避免该问题:

SELECT * FROM employees WHERE salary < 5000

UNION ALL

SELECT * FROM employees WHERE commission_pct IS NOT NULL;

3.2.4 避免对查询结果进行排序

当SQL语句中包含ORDER BY关键字时,索引也不一定会被使用。例如,以下查询语句:

SELECT * FROM employees WHERE department_id=10 ORDER BY salary DESC;

可以通过将排序操作移至应用程序层来避免该问题:

SELECT * FROM employees WHERE department_id=10;

在应用程序中对查询结果进行排序。

3.2.5 避免扫描超过20%的数据块

当SQL语句需要扫描超过20%的数据块时,索引也不一定会被使用。可以通过调整排序方式、添加WHERE子句等方式来减小扫描数据块的数量。

4. 总结

Oracle不走索引的情况有多种,包括非等值条件下的查询、NULL值查询、多列索引的顺序问题等。为避免这种情况,需要在建立索引时根据业务需求选择正确的列和类型,并优化SQL语句,避免使用变量或函数包装列名、NOT、OR或ORDER BY关键字,以及避免扫描超过20%的数据块。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

数据库标签