数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
使用索引的误区之一:没有使用复合索引的前导列导致查询不使用索引

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

使用索引的误区之一:没有使用复合索引的前导列导致查询不使用索引

oracle中,我们经常以为建立了索引,sql查询的时候就会如我们所希望的那样使用索引,事实上,oracle只会在一定条件下使用索引,这里我们总结数第一点:oracle会在条件中包含了前导列时使用索引,即查询条件中必须使用索引中的第一个列,请看下面的例子

SQL> select * from tab;

 

TNAME                          TABTYPE  CLUSTERID

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

BONUS                          TABLE

DEPT                           TABLE

DUMMY                          TABLE

EMP                            TABLE

SALGRADE                       TABLE

 

建立一个联合索引(注意复合索引的索引列顺序)

SQL> create index emp_id1 on emp(empno,ename,deptno);

 

Index created

 

建立一个单键索引

SQL> create index emp_id2 on emp(sal);

 

Index created

 

 

SQL> select table_name,index_name from user_indexes

  2  where table_name='EMP';

 

TABLE_NAME                     INDEX_NAME

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

EMP                            EMP_ID1

EMP                            EMP_ID2

 

SQL> SELECT * FROM USER_IND_COLUMNS

  2  /

 

INDEX_NAME                     TABLE_NAME                     COLUMN_NAME                                                                      COLUMN_POSITION COLUMN_LENGTH CHAR_LENGTH DESCEND

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

EMP_ID1                        EMP                            EMPNO                                                                                          1            22           0 ASC

EMP_ID1                        EMP                            ENAME                                                                                          2            10          10 ASC

EMP_ID1                        EMP                            DEPTNO                                                                                         3            22           0 ASC

EMP_ID2                        EMP                            SAL                                                                                            1            22           0 ASC

 

下面的查询由于没有使用到复合索引的前导列,所以没有使用索引

 select job, empno from emp where ename='RICH';

 

PLAN_TABLE_OUTPUT

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

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

| Id  | Operation            |  Name       | Rows  | Bytes | Cost  |

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

|   0 | SELECT STATEMENT     |             |       |       |       |

|*  1 |  TABLE ACCESS FULL   | EMP         |       |       |       |

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

Predicate Information (identified by operation id):

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

   1 - filter("EMP"."ENAME"='RICH')

Note: rule based optimization

 

14 rows selected

 

 

下面的查询也由于没有使用到复合索引的前导列,所以没有使用索引

select job, empno from emp where deptno=30;

 

PLAN_TABLE_OUTPUT

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

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

| Id  | Operation            |  Name       | Rows  | Bytes | Cost  |

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

|   0 | SELECT STATEMENT     |             |       |       |       |

|*  1 |  TABLE ACCESS FULL   | EMP         |       |       |       |

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

Predicate Information (identified by operation id):

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

   1 - filter("EMP"."DEPTNO"=30)

Note: rule based optimization

 

14 rows selected

 

 

 

下面的查询使用了复合索引中的前导列,所以查询走索引了

select job, empno from emp where empno=7777;

 

PLAN_TABLE_OUTPUT

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

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

| Id  | Operation                   |  Name       | Rows  | Bytes | Cost  |

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

|   0 | SELECT STATEMENT            |             |       |       |       |

|   1 |  TABLE ACCESS BY INDEX ROWID| EMP         |       |       |       |

|*  2 |   INDEX RANGE SCAN          | EMP_ID1     |       |       |       |

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

Predicate Information (identified by operation id):

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

   2 - access("EMP"."EMPNO"=7777)

Note: rule based optimization

 

15 rows selected

 

 

 

 

下面的查询使用了复合索引中的第一列和第二列,所以查询走索引了

select job, empno from emp where empno=7777 and ename='RICH';

 

PLAN_TABLE_OUTPUT

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

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

| Id  | Operation                   |  Name       | Rows  | Bytes | Cost  |

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

|   0 | SELECT STATEMENT            |             |       |       |       |

|   1 |  TABLE ACCESS BY INDEX ROWID| EMP         |       |       |       |

|*  2 |   INDEX RANGE SCAN          | EMP_ID1     |       |       |       |

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

Predicate Information (identified by operation id):

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

   2 - access("EMP"."EMPNO"=7777 AND "EMP"."ENAME"='RICH')

Note: rule based optimization

 

15 rows selected

 

 

 

使用了复合索引的全部列,所以走索引了,另外由于选了了索引中没有包含的列(job),

所以进行索引全表扫描得到满足条件的rowid后,还要到表中检索相应的行

select job, empno from emp where empno=7777 and ename='RICH' and deptno=30;

 

PLAN_TABLE_OUTPUT

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

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

| Id  | Operation                   |  Name       | Rows  | Bytes | Cost  |

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

|   0 | SELECT STATEMENT            |             |       |       |       |

|   1 |  TABLE ACCESS BY INDEX ROWID| EMP         |       |       |       |

|*  2 |   INDEX RANGE SCAN          | EMP_ID1     |       |       |       |

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

Predicate Information (identified by operation id):

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

   2 - access("EMP"."EMPNO"=7777 AND "EMP"."ENAME"='RICH' AND "EMP"."DEP

              TNO"=30)

Note: rule based optimization

 

16 rows selected

 

 

 

 

使用了复合索引的全部列,所以走索引了,而且由于所有选择的列都包含在索引中,所以仅仅进行了索引范围扫描

select empno from emp where empno=7777 and ename='RICH' and deptno=30;

 

PLAN_TABLE_OUTPUT

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

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

| Id  | Operation            |  Name       | Rows  | Bytes | Cost  |

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

|   0 | SELECT STATEMENT     |             |       |       |       |

|*  1 |  INDEX RANGE SCAN    | EMP_ID1     |       |       |       |

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

Predicate Information (identified by operation id):

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

   1 - access("EMP"."EMPNO"=7777 AND "EMP"."ENAME"='RICH' AND "EM

              P"."DEPTNO"=30)

Note: rule based optimization

 

15 rows selected

 




相关文章

相关软件