Oracle如何查询访问同一表的两个以上索引(二)

经常看到有人提出这样的疑问,我在同一张表上建立了多个索引,为什么Oracle每次都选择一个,而不能同时利用多个索引呢。一般来说,常见的访问同一张表的两个以上索引,存在三种情况,AND-EQUAL、INDEX HASH JOIN和BITMAP INDEX AND/OR。

此外,还有一个设计上的疑问,如果有A、B、C三个字段,都可能作为查询条件,是建立多个复合索引好,还是建立三个单列的索引。这个问题之所以不好回答是因为和业务或者说和查询的模式有很大的关系,不过如果理解了Oracle什么时候会选择一个以上的索引来访问表,就会对于理解如何设计合理的索引有很大的帮助。

简单介绍一下BITMAP索引的AND/OR执行计划。

首先建立一个测试表:

SQL> DROP TABLE T_DOUBLE_IND PURGE;

Table dropped.

SQL> CREATE TABLE T_DOUBLE_IND

2  (ID NUMBER,

3  NAME VARCHAR2(30),

4  TYPE VARCHAR2(30),

5  CONTENTS VARCHAR2(4000));

Table created.

SQL> INSERT INTO T_DOUBLE_IND

2  SELECT ROWNUM,

3  OBJECT_NAME,

4  OBJECT_TYPE,

5  LPAD('A', 1000, 'A')

6  FROM DBA_OBJECTS;

75856 rows created.

SQL> CREATE INDEX IND_DOUBLE_NAME

2  ON T_DOUBLE_IND (NAME);

Index created.

SQL> CREATE INDEX IND_DOUBLE_TYPE

2  ON T_DOUBLE_IND (TYPE);

Index created.

现在建立了一个测试表和两个索引,下面看看如何使用BITMAP索引的AND操作:

更多精彩内容:http://www.bianceng.cn/database/Oracle/

SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T_DOUBLE_IND')

PL/SQL procedure successfully completed.

SQL> SET AUTOT ON EXP

SQL> SELECT ID, NAME, TYPE

2  FROM T_DOUBLE_IND

3  WHERE NAME = 'T_DOUBLE_IND'

4  AND TYPE = 'TABLE';

ID NAME                           TYPE

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

75737 T_DOUBLE_IND                   TABLE

Execution Plan

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

Plan hash value: 3887138334

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

| Id| Operation                   | Name            | Rows | Bytes | Cost (%CPU)| Time     |

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

| 0 | SELECT STATEMENT            |                 |    1 |    37 |     3   (0)| 00:00:01 |

|*1 |  TABLE ACCESS BY INDEX ROWID| T_DOUBLE_IND    |    1 |    37 |     3   (0)| 00:00:01 |

|*2 |   INDEX RANGE SCAN          | IND_DOUBLE_NAME |    2 |       |     1   (0)| 00:00:01 |

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

Predicate Information (identified by operation id):

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

1 - filter("TYPE"='TABLE')

2 - access("NAME"='T_DOUBLE_IND')

SQL> SELECT /*+ INDEX_COMBINE(A IND_DOUBLE_NAME IND_DOUBLE_TYPE) */ ID, NAME, TYPE

2  FROM T_DOUBLE_IND A

3  WHERE NAME = 'T_DOUBLE_IND'

4  AND TYPE = 'TABLE';

时间: 2024-11-02 09:50:45

Oracle如何查询访问同一表的两个以上索引(二)的相关文章

Oracle如何查询访问同一表的两个以上索引(三)INDEX HASH JOIN执行计划

经常看到有人提出这样的疑问,我在同一张表上建立了多个索引,为什么Oracle每次都选择一个,而不能同时利用多个索引呢.一般来说,常见的访问同一张表的两个以上索引,存在三种情况,AND-EQUAL.INDEX HASH JOIN和BITMAP INDEX AND/OR. 此外,还有一个设计上的疑问,如果有A.B.C三个字段,都可能作为查询条件,是建立多个复合索引好,还是建立三个单列的索引.这个问题之所以不好回答是因为和业务或者说和查询的模式有很大的关系,不过如果理解了Oracle什么时候会选择一个

Oracle如何查询访问同一表的两个以上索引(一)介绍AND-EQUAL

经常看到有人提出这样的疑问,我在同一张表上建立了多个索引,为什么Oracle每次都选择一个,而不能同时利用多个索引呢.一般来说,常见的访问同一张表的两个以上索引,存在三种情况,AND-EQUAL.INDEX HASH JOIN和BITMAP INDEX AND/OR. 此外,还有一个设计上的疑问,如果有A.B.C三个字段,都可能作为查询条件,是建立多个复合索引好,还是建立三个单列的索引.这个问题之所以不好回答是因为和业务或者说和查询的模式有很大的关系,不过如果理解了Oracle什么时候会选择一个

查询一张表中两个字段重复的数据并得到其主键?

问题描述 希望各位路过的大侠 帮小弟一把.感激不尽. 如何查询一张表中两个字段都重复的数据以及每组中的第一条数据的主键? 情况如下: A表: a1 a2 a3  a4   都列a1     a2            a3                  a41       m              n                   o2       m              n                   k3       j                k     

ORACLE 如何查询被锁定表及如何解锁释放session_oracle

ORACLE EBS操作某一个FORM界面,或者后台数据库操作某一个表时发现一直出于"假死"状态,可能是该表被某一用户锁定,导致其他用户无法继续操作 复制代码 代码如下: --锁表查询SQLSELECT object_name, machine, s.sid, s.serial# FROM gv$locked_object l, dba_objects o, gv$session s WHERE l.object_id = o.object_id AND l.session_id =

如何在oracle中查询所有用户表的表名、主键名称、索引、外键等

1.查找表的所有索引(包括索引名,类型,构成列):  select t.*,i.index_type from user_ind_columns t,user_indexes i where t.index_name = i.index_name and t.table_name = i.table_name and t.table_name = 要查询的表  2.查找表的主键(包括名称,构成列):  select cu.* from user_cons_columns cu, user_con

Oracle查询用户所有表

下面为您介绍的语句用于实现Oracle查询用户所有表,如果您对oracle查询方面感兴趣的话,不妨一看.  select * from all_tab_comments -- 查询所有用户的表,视图等 select * from user_tab_comments -- 查询本用户的表,视图等 select * from all_col_comments --查询所有用户的表的列名和注释. select * from user_col_comments -- 查询本用户的表的列名和注释 sele

Oracle分页查询格式(十三)

Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用. 这篇介绍HASH SORT CLUSTER表对分页查询的帮助. Oracle分页查询格式(一):http://yangtingkun.itpub.net/post/468/100278 Oracle分页查询格式(二):http://yangtingkun.itpub.net/post/468/101703 Oracle分页查询格式(三):http://yangtingkun.itpub.net/post/468/104595 O

Oracle 数据库查询最近添加的50条数据

问题描述 Oracle数据库查询最近添加的50条数据 解决方案 解决方案二:要有一个可判断顺序的字段,比如递增字段,或者日期,你orderbydesc然后取前50就行解决方案三:selecttop50*fromAorderbyAtimedesc解决方案四:Oracle没有top,但是有rowsnumber解决方案五:oracle的rownumhttp://www.cnblogs.com/zjrstar/archive/2006/08/31/491090.html解决方案六:引用1楼bdmh的回复

过滤两个字段-关于oracle sql查询同一个表,根据不同字段过滤去重的问题

问题描述 关于oracle sql查询同一个表,根据不同字段过滤去重的问题 select j.xmbhid,j.xmmc,j.scjd,j.xmzt from jhxx_new j where j.xxdm='4111010001' and j.lrjh in (209,210,244) order by xmbhid,scjd,xmzt 重复记录中所处阶段三个状态(0,2,3),项目状态(xmzt)两个状态(0,1) 先要查看所处阶段最大值,并且项目状态是1,即第二个图片的显示效果,求大神们帮