首頁 資料庫 mysql教程 复合索引的filter和access(二)

复合索引的filter和access(二)

Jun 07, 2016 pm 04:40 PM
access filter ht 索引

上一篇blog http://www.dbaxiaoyu.com/archives/2354 简单的讲述了index range scan的filter和access的区别,这里再进行一点补充,索引对于sql优化的意义确实是非常大的。 [oracle@redhat_ora11g ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Prod

上一篇blog http://www.dbaxiaoyu.com/archives/2354 简单的讲述了index range scan的filter和access的区别,这里再进行一点补充,索引对于sql优化的意义确实是非常大的。

[oracle@redhat_ora11g ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on Mon Nov 3 06:38:37 2014

Copyright (c) 1982, 2013, Oracle.  All rights reserved.

SQL> create table tbak03 as select * from dba_objects;

Table created.

SQL> create index ind_tbak_owner_objid_type on tbak03(owner,object_id,object_type);

Index created.

SQL> select * from tbak03 where owner='SYS' and object_type='INDEX';

1212 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 3404448970

---------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                      | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                           |  1061 |   214K|   163   (0)| 00:00:02 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TBAK03                    |  1061 |   214K|   163   (0)| 00:00:02 |
|*  2 |   INDEX RANGE SCAN          | IND_TBAK_OWNER_OBJID_TYPE |   148 |       |   159   (0)| 00:00:02 |
---------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OWNER"='SYS' AND "OBJECT_TYPE"='INDEX')
       filter("OBJECT_TYPE"='INDEX')

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
         84  recursive calls
          0  db block gets
        536  consistent gets
          1  physical reads
          0  redo size
     130958  bytes sent via SQL*Net to client
       1403  bytes received via SQL*Net from client
         82  SQL*Net roundtrips to/from client
          6  sorts (memory)
          0  sorts (disk)
       1212  rows processed

这个sql走的是index range scan,access过滤的条件是(“OWNER”=’SYS’ AND “OBJECT_TYPE”=’INDEX’),但是filter中又出现了(“OBJECT_TYPE”=’INDEX’),这个是表示优化器在index range scan扫描时不能绝对保证扫描leaf block满足(“OBJECT_TYPE”=’INDEX’),所以需要在index range scan完成后再次对object_type进行过滤。

我们再看下面的sql语句的执行计划:

SQL> select * from tbak03 where owner='SYS' and object_type='INDEX' and object_id>10000;

161 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3404448970

---------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                      | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                           |   120 | 24840 |   139   (0)| 00:00:02 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TBAK03                    |   120 | 24840 |   139   (0)| 00:00:02 |
|*  2 |   INDEX RANGE SCAN          | IND_TBAK_OWNER_OBJID_TYPE |   125 |       |   135   (0)| 00:00:02 |
---------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OWNER"='SYS' AND "OBJECT_ID">10000 AND "OBJECT_TYPE"='INDEX' AND "OBJECT_ID" IS
              NOT NULL)
       filter("OBJECT_TYPE"='INDEX')

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
          5  recursive calls
          0  db block gets
        248  consistent gets
          0  physical reads
          0  redo size
      18929  bytes sent via SQL*Net to client
        633  bytes received via SQL*Net from client
         12  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        161  rows processed

虽然同样是index range scan,access部分出现了三个条件值时,但是filter中还是出现了(“OBJECT_TYPE”=’INDEX’)这个条件,同样这里表示优化器在index range scan扫描时候不能保证扫描的leaf block绝对满足(“OBJECT_TYPE”=’INDEX’)。

上面两个sql都可以总结为一类sql,就是在index range scan时候,在谓词条件中如果复合索引的部分列没有包含或者没有等值谓词过滤条件,而且出现了此列在复合索引相关位置的后面的列的谓词条件,那么后面相关的列肯定需要走filter,index range scan扫描leaf block是没有办法确定扫描的列都是满足access的条件,当然leaf block扫描时就可能会扫描一些不满足access部分涉及的谓词条件的leaf block

而如果索引的所有列都出现在查询中,而且都是等值的谓词条件,那么索引的index range scan不会出现filter

SQL> select * from tbak03 where owner='SYS' and object_type='INDEX' and object_id=10000;

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 3404448970

---------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                      | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                           |     1 |   207 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TBAK03                    |     1 |   207 |     1   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IND_TBAK_OWNER_OBJID_TYPE |     1 |       |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OWNER"='SYS' AND "OBJECT_ID"=10000 AND "OBJECT_TYPE"='INDEX')

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
       1343  bytes sent via SQL*Net to client
        512  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed

如果存在不等值的查询,只要保证这个不等值的谓词是复合索引的最后列,index range scan扫描时不会出现filter部分,索引范围扫描时候也能够精确的定位到需要扫描的leaf block

SQL> create index ind_tbak_owner_type_objid on tbak03(owner,object_type,object_id);

Index created.

SQL> select * from tbak03 where owner='SYS' and object_type='INDEX' and object_id>10000;

3606 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1247367584

---------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                      | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                           |   579 | 57321 |    29   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TBAK03                    |   579 | 57321 |    29   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IND_TBAK_OWNER_TYPE_OBJID |   579 |       |     5   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OWNER"='SYS' AND "OBJECT_TYPE"='INDEX' AND "OBJECT_ID">10000 AND "OBJECT_ID" IS
              NOT NULL)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        667  consistent gets
         15  physical reads
          0  redo size
     406174  bytes sent via SQL*Net to client
       3163  bytes received via SQL*Net from client
        242  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       3606  rows processed

下面我们来看index skip scan的access和filter部分有何区别:

SQL> select * from tbak03 where object_id=10000;


Execution Plan
----------------------------------------------------------
Plan hash value: 846494542

---------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                      | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                           |     1 |    99 |     6   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TBAK03                    |     1 |    99 |     6   (0)| 00:00:01 |
|*  2 |   INDEX SKIP SCAN           | IND_TBAK_OWNER_OBJID_TYPE |     1 |       |     5   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_ID"=10000)
       filter("OBJECT_ID"=10000)


Statistics
----------------------------------------------------------
          3  recursive calls
          0  db block gets
         30  consistent gets
          0  physical reads
          0  redo size
       1615  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

index skip scan时候好像谓词部分access和filter也同时出现了,而且还是针对同一个值

再来看看下面的sql语句又出现index skip scan:

SQL> select * from tbak03 where object_id=10000 and owner>'SYS';

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 846494542

---------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                      | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                           |     1 |    99 |     6   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TBAK03                    |     1 |    99 |     6   (0)| 00:00:01 |
|*  2 |   INDEX SKIP SCAN           | IND_TBAK_OWNER_OBJID_TYPE |     1 |       |     5   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OWNER">'SYS' AND "OBJECT_ID"=10000 AND "OWNER" IS NOT NULL)
       filter("OBJECT_ID"=10000)

Statistics
----------------------------------------------------------
         39  recursive calls
          0  db block gets
         47  consistent gets
          0  physical reads
          0  redo size
       1343  bytes sent via SQL*Net to client
        512  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          6  sorts (memory)
          0  sorts (disk)
          0  rows processed

索引IND_TBAK_OWNER_OBJID_TYPE是(owner,object_id,object_type)的复合索引,但是上面这个查询没有出现我们熟知的index range scan,然后在filter部分再次出现object_id的过滤,而是直接以index skip scan的方式来扫描,然后再filter部分再次出现object_id的等值过滤,这跟我们熟知的index range scan时候当索引的前导列不存在时才出现是对立的。

优化器在index skip scan时是这么完成的,首先通过object_id=10000 and owner>’SYS’条件从root节点找到branch block再到leaf block然后索引范围扫描,当发现object_id不再满足条件时,则重新回到了root节点再到下一个定位的branch block和leaf block做范围扫描,跟之前index range scan所不同的就是,index skip scan会重新回到branch block再到leaf block,类似于一个索引的迭代,而index range scan则大多表现为一旦定位到branch block和leaf block后,就只会在leaf block通过双向指针滑动来扫描满足条件的leaf block,对于一些复合索引如果前导列不同值较少,然后后导列不同值较多,优化器评估object_id=10000 and owner>’SYS’这类谓词条件时会走index skip scan来完成查询。

接下来如果是下列谓词条件的话,优化器多半不会选择index range scan来完成查询。

SQL> create index ind_test02 on xiaoyu03(owner,object_id,data_object_id);

Index created.

SQL> select * from xiaoyu03 where object_id
177 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 4138876341

------------------------------------------------------------------------------
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          |  2296 |   197K|    43   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| XIAOYU03 |  2296 |   197K|    43   (0)| 00:00:01 |
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("OBJECT_ID"

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        151  consistent gets
          0  physical reads
          0  redo size
      12358  bytes sent via SQL*Net to client
        644  bytes received via SQL*Net from client
         13  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        177  rows processed

SQL> select /*+index_ffs(xiaoyu03 IND_OBJID_DATAID)*/* from xiaoyu03 where object_id
177 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 4138876341

------------------------------------------------------------------------------
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          |  2296 |   197K|    43   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| XIAOYU03 |  2296 |   197K|    43   (0)| 00:00:01 |
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("OBJECT_ID"

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        151  consistent gets
          0  physical reads
          0  redo size
      12358  bytes sent via SQL*Net to client
        644  bytes received via SQL*Net from client
         13  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        177  rows processed

这里的hint为什么无法生效了,索引快速扫描时优化器是没有办法回表的,这里由于需要回表,hint将会被忽略掉。

SQL> select /*+index(xiaoyu03)*/* from xiaoyu03 where object_id

177 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 3964829153

------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2296 | 197K| 78 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| XIAOYU03 | 2296 | 197K| 78 (0)| 00:00:01 |
|* 2 | INDEX FULL SCAN | IND_TEST02 | 2296 | | 31 (0)| 00:00:01 |
------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - filter("OBJECT_ID"

Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
68 consistent gets
11 physical reads
0 redo size
23874 bytes sent via SQL*Net to client
644 bytes received via SQL*Net from client
13 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
177 rows processed

强制走index,需要注意的index full scan其实也是index range scan,只是index full scan时oracle需要扫描所有的leaf block,但是其实扫描的机制还是一样的。

再来看另外比较常见的or和and来使用索引的两类查询,我们先来看下包含多个谓词条件的and查询:

SQL> create index ind_objid_dataobjid on tbak03(object_id,data_object_id);

Index created.

SQL> select * from tbak03 where object_id between 10000 and 10019 and data_object_id between 9980 and 10092;

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 3552957621

---------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                     |     1 |    99 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TBAK03              |     1 |    99 |     3   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IND_OBJID_DATAOBJID |     1 |       |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_ID">=10000 AND "DATA_OBJECT_ID">=9980 AND "OBJECT_ID"               "DATA_OBJECT_ID"        filter("DATA_OBJECT_ID"=9980)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          2  consistent gets
          1  physical reads
          0  redo size
       1343  bytes sent via SQL*Net to client
        512  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          0  rows processed

对于上述这类包含两个不同谓词过滤条件的and条件,需要明确的and情况下oracle很多情况都会只用一个索引来完成查询,然后回表进行第二次过滤,但是如果是需要两个索引回表才能完成查询,优化器就只能选择全表扫描或者转换bitmap后做bitmap and回表。

SQL> drop index ind_objid_dataobjid;

Index dropped.
SQL> create index ind_objid on tbak03(object_id);

Index created.

SQL> create index ind_dataobjid on tbak03(data_object_id);

Index created.

SQL>  select * from tbak03 where object_id between 8809 and 10003 and data_object_id between 19980 and 30002;

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 2924755239

--------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |               |    14 |  1386 |    13  (16)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID     | TBAK03        |    14 |  1386 |    13  (16)| 00:00:01 |
|   2 |   BITMAP CONVERSION TO ROWIDS    |               |       |       |            |          |
|   3 |    BITMAP AND                    |               |       |       |            |          |
|   4 |     BITMAP CONVERSION FROM ROWIDS|               |       |       |            |          |
|   5 |      SORT ORDER BY               |               |       |       |            |          |
|*  6 |       INDEX RANGE SCAN           | IND_DATAOBJID |  1182 |       |     4   (0)| 00:00:01 |
|   7 |     BITMAP CONVERSION FROM ROWIDS|               |       |       |            |          |
|   8 |      SORT ORDER BY               |               |       |       |            |          |
|*  9 |       INDEX RANGE SCAN           | IND_OBJID     |  1182 |       |     4   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   6 - access("DATA_OBJECT_ID">=19980 AND "DATA_OBJECT_ID"    9 - access("OBJECT_ID">=8809 AND "OBJECT_ID"

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          2  consistent gets
          1  physical reads
          0  redo size
       1343  bytes sent via SQL*Net to client
        512  bytes received via SQL*Net from client
          1  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          0  rows processed

这里oracle将其中的索引b tree的rowid先转化为bitmap,然后将两个bitmap进行bitmap and最后再转化为rowed回表,一般而言出现这类执行计划都是建议创建更优秀的复合索引来较少sql语句消耗的资源。

再来看下包含两个谓词条件的or查询:

SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  5svu4zamsud9q, child number 0
-------------------------------------
select /*+gather_plan_statistics*/object_name from tbak03 where
object_id between 10000 and 10019 or data_object_id between 8080 and
10092

Plan hash value: 2095522732

-----------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name          | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
-----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |               |      1 |        |    217 |00:00:00.01 |      76 |      1 |
|   1 |  CONCATENATION               |               |      1 |        |    217 |00:00:00.01 |      76 |      1 |
|   2 |   TABLE ACCESS BY INDEX ROWID| TBAK03        |      1 |     21 |     20 |00:00:00.01 |      10 |      0 |
|*  3 |    INDEX RANGE SCAN          | IND_OBJID     |      1 |     21 |     20 |00:00:00.01 |       4 |      0 |
|*  4 |   TABLE ACCESS BY INDEX ROWID| TBAK03        |      1 |    181 |    197 |00:00:00.01 |      66 |      1 |
|*  5 |    INDEX RANGE SCAN          | IND_DATAOBJID |      1 |    201 |    197 |00:00:00.01 |      16 |      1 |
-----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("OBJECT_ID">=10000 AND "OBJECT_ID"    4 - filter((LNNVL("OBJECT_ID"=10000)))
   5 - access("DATA_OBJECT_ID">=8080 AND "DATA_OBJECT_ID"
26 rows selected.

这个concatenation是类似oracle的union all,就是分别通过rowid回表,但是需要注意的是其中 谓词信息4 – filter(LNNVL(“DATA_OBJECT_ID”=9980))去掉了重复满足多个条件的数据,这样可以保证通过这种方式取回的数据是准确的。

可能有朋友会问到了,如果对于or创建一个复合索引是否可以避免上述这类concatenation方式了,其实or的情况下是不能单单利用一次index range scan来完成查询的,即使这个索引是个包含两个过滤条件的复合索引,优化器如果走index range scan,也需要走两次index range scan回表然后concatenation的方式,或者直接走一次index full scan然后回表。

SQL> create index ind_objid_dataobjid on tbak03(object_id,data_object_id);

Index created.
SQL> select /*+index(tbak03 ind_objid_dataobjid)*/object_name from tbak03 where object_id between 10000 and 10019 or data_object_id between 8080 and 10092;

217 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 392751159

---------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                     |   222 |  6660 |   214   (1)| 00:00:03 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TBAK03              |   222 |  6660 |   214   (1)| 00:00:03 |
|*  2 |   INDEX FULL SCAN           | IND_OBJID_DATAOBJID |   222 |       |   210   (1)| 00:00:03 |
---------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("DATA_OBJECT_ID"=8080 OR "OBJECT_ID"               "OBJECT_ID">=10000)

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        254  consistent gets
        208  physical reads
          0  redo size
       7594  bytes sent via SQL*Net to client
        677  bytes received via SQL*Net from client
         16  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
        217  rows processed

再来另外一种更简单的or查询,需要注意的in (‘A’,’B’…)这种查询,oracle的查询转换也会改写为or的形式,由于都是同一个列的谓词条件,优化器大多数会走比concatenation更加高效的inlist iterator,inlist iterator的方式类似于在反复的从root节点到branch再到leaf block来定位满足条件的键值,然后回表,而concatenation的方式则是通过多次index range scan回表的方式合并结果集。

SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));


PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  1guyuwmd6wsj6, child number 0
-------------------------------------
 select /*+gather_plan_statistics*/* from tbak03 where object_id=90 or
object_id=29292


Plan hash value: 3397823708


-------------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |           |      1 |        |      2 |00:00:00.01 |       7 |      2 |
|   1 |  INLIST ITERATOR             |           |      1 |        |      2 |00:00:00.01 |       7 |      2 |
|   2 |   TABLE ACCESS BY INDEX ROWID| TBAK03    |      2 |      2 |      2 |00:00:00.01 |       7 |      2 |
|*  3 |    INDEX RANGE SCAN          | IND_OBJID |      2 |      2 |      2 |00:00:00.01 |       5 |      2 |
-------------------------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------


   3 - access(("OBJECT_ID"=90 OR "OBJECT_ID"=29292))




21 rows selected.

关于索引的filter和access部分这里xiaoyu再举出上述的例子以供大家参考,下篇将对bitmap索引进行探讨。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Windows11怎麼停用後台應用程式_Windows11停用後台應用程式教學 Windows11怎麼停用後台應用程式_Windows11停用後台應用程式教學 May 07, 2024 pm 04:20 PM

1、在Windows11中開啟設定。您可以使用Win+I快捷方式或任何其他方法。 2、前往應用程式部分,然後按一下應用程式和功能。 3、尋找要阻止在背景執行的應用程式。點擊三點按鈕並選擇進階選項。 4、找到【後台應用程式權限】部分並選擇所需的值。預設情況下,Windows11設定電源最佳化模式。它允許Windows管理應用程式在背景的工作方式。例如,一旦啟用省電模式以保留電池,系統將自動關閉所有應用程式。 5.選擇【從不】可防止應用程式在背景運行。請注意,如果您注意到程式不會向您發送通知、無法更新資料等,您可

deepseek怎麼轉換pdf deepseek怎麼轉換pdf Feb 19, 2025 pm 05:24 PM

DeepSeek 無法直接將文件轉換為 PDF。根據文件類型,可以使用不同方法:常見文檔(Word、Excel、PowerPoint):使用微軟 Office、LibreOffice 等軟件導出為 PDF。圖片:使用圖片查看器或圖像處理軟件保存為 PDF。網頁:使用瀏覽器“打印成 PDF”功能或專用的網頁轉 PDF 工具。不常見格式:找到合適的轉換器,將其轉換為 PDF。選擇合適的工具並根據實際情況制定方案至關重要。

oracle怎麼讀取dbf文件 oracle怎麼讀取dbf文件 May 10, 2024 am 01:27 AM

Oracle 可以透過以下步驟讀取 dbf 檔案:建立外部表,引用 dbf 檔案;查詢外部表,檢索資料;將資料匯入 Oracle 表。

Java反射機制如何修改類別的行為? Java反射機制如何修改類別的行為? May 03, 2024 pm 06:15 PM

Java反射機制允許程式動態修改類別的行為,無需修改原始程式碼。透過Class物件操作類,可以透過newInstance()建立實例,修改私有欄位值,呼叫私有方法等。但應謹慎使用反射,因為它可能會導致意外的行為和安全問題,並有性能開銷。

Java 函數開發中常見的異常類型及其修復措施 Java 函數開發中常見的異常類型及其修復措施 May 03, 2024 pm 02:09 PM

Java函數開發中常見的異常類型及其修復措施在Java函數開發過程中,可能會遇到各種異常,影響函數的正確執行。以下是常見的異常類型及其修復措施:1.NullPointerException描述:當存取一個還未初始化的物件時拋出。修復措施:確保在使用物件之前對其進行非空檢查。範例程式碼:try{Stringname=null;System.out.println(name.length());}catch(NullPointerExceptione){

vue中iframe跨域的方法 vue中iframe跨域的方法 May 02, 2024 pm 10:48 PM

在 Vue 中解決 iframe 跨域問題的方法:CORS:啟用後端伺服器中的 CORS 支持,在 Vue 中使用 XMLHttpRequest 或 fetch API 發送 CORS 請求。 JSONP:使用後端伺服器中的 JSONP 端點,在 Vue 中動態載入 JSONP 腳本。代理伺服器:設定代理伺服器轉送請求,在 Vue 中使用第三方程式庫(如 axios)傳送請求並設定代理伺服器 URL。

解讀 Botanix:網路資產管理去中心化的 BTC L2(附互動教學) 解讀 Botanix:網路資產管理去中心化的 BTC L2(附互動教學) May 08, 2024 pm 06:40 PM

昨日,BotanixLabs宣布累計完成1,150萬美元融資,PolychainCapital、PlaceholderCapital等參投。融資將用於建構去中心化的EVM等效BTCL2Botanix。 Spiderchain結合了EVM的易用性與比特幣的安全性。自2023年11月測試網路上線以來,已有超過20萬個活躍位址。 Odaily將於本文解析Botanix的特色機制與測試網交互流程。 Botanix依照官方定義,Botanix是基於比特幣建構的去中心化的圖靈完備L2EVM,由兩個核心組件以太坊虛

oracle中explain的用法 oracle中explain的用法 May 03, 2024 am 12:06 AM

Oracle中的EXPLAIN指令用於分析SQL語句的執行計劃,使用方法為在SQL語句前加入EXPLAIN關鍵字。 EXPLAIN結果包含ID、運算元類型、行數估計、成本估計、輸出行數估計、存取謂詞和過濾謂詞等信息,可用於最佳化查詢效能,標識高代價運算子和可能受益於最佳化技術的表。

See all articles