暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 19C 索引跳过扫描

原创 Asher.HU 2021-02-04
768


一个索引跳跃扫描时发生复合索引的初始列是“跳过”或在查询未指定。


8.3.6.1当优化器考虑索引跳过扫描时

通常,跳过扫描索引块比扫描表块快,并且比执行全索引扫描快。

当满足以下条件时,优化器将考虑跳过扫描:

  • 在查询谓词中未指定复合索引的前导列。 

    例如,查询谓词未引用该cust_gender列,并且复合索引键为(cust_gender,cust_email)

  • 复合索引的前导列中几乎没有不同的值(选择性差),但是索引的非前导键中存在许多不同的值。

    例如,如果组合索引键为(cust_gender,cust_email),则该cust_gender列只有两个不同的值,但cust_email有数千个。

 

8.3.6.2索引跳过扫描如何工作

索引跳过扫描在逻辑上将组合索引拆分为较小的子索引

索引的前几列中不同值的数量确定逻辑子索引的数量。数字越小,优化器必须创建的逻辑子索引越少,并且扫描变得越有效。扫描将分别读取每个逻辑索引,并在不超前的列上“跳过”不满足过滤条件的索引块。

 

8.3.6.3索引跳过扫描:示例

本示例使用索引跳过扫描来满足对sh.customers的查询

customers表包含一列,cust_gender其值为MF以用户身份登录数据库后sh,您可以在列(cust_gender, cust_email上创建一个复合索引,如下所示:

CREATE INDEX cust_gender_email_ix
  ON sh.customers (cust_gender, cust_email);

从概念上讲,该索引的一部分可能看起来如下所示,其性别值为FM作为该索引的前沿。

F,Wolf@company.example.com,rowid
F,Wolsey@company.example.com,rowid
F,Wood@company.example.com,rowid
F,Woodman@company.example.com,rowid
F,Yang@company.example.com,rowid
F,Zimmerman@company.example.com,rowid
M,Abbassi@company.example.com,rowid
M,Abbey@company.example.com,rowid

您在sh.customers表中为客户运行以下查询

SELECT * 
FROM   sh.customers 
WHERE  cust_email = 'Abbey@company.example.com';

customers_gender_email即使cust_gender未在WHERE子句中指定,数据库也可以使用索引的跳过扫描在样本索引中,前导列cust_gender具有两个可能的值:FM数据库在逻辑上将索引分为两个。一个子索引具有key F,其条目的格式如下:

F,Wolf@company.example.com,rowid
F,Wolsey@company.example.com,rowid
F,Wood@company.example.com,rowid
F,Woodman@company.example.com,rowid
F,Yang@company.example.com,rowid
F,Zimmerman@company.example.com,rowid

第二个子索引具有key M,其条目具有以下形式:

M,Abbassi@company.example.com,rowid
M,Abbey@company.example.com,rowid


在搜索电子邮件地址为客户的记录时Abbey@company.example.com,数据库首先搜索具有前导值F的子索引,然后搜索具有前导值的子索引M从概念上讲,数据库按以下方式处理查询:

( SELECT * 
  FROM   sh.customers 
  WHERE  cust_gender = 'F' 
  AND    cust_email = 'Abbey@company.example.com' )
UNION ALL
( SELECT * 
  FROM   sh.customers 
  WHERE  cust_gender = 'M'
  AND    cust_email = 'Abbey@company.example.com' )


查询计划如下:

SQL_ID  d7a6xurcnx2dj, child number 0
-------------------------------------
SELECT * FROM   sh.customers WHERE  cust_email = 'Abbey@company.example.com'
 
Plan hash value: 797907791
 
-----------------------------------------------------------------------------------------
|Id| Operation                          | Name               |Rows|Bytes|Cost(%CPU)|Time|
-----------------------------------------------------------------------------------------
| 0|SELECT STATEMENT                    |                      |  |    |10(100)|        |
| 1| TABLE ACCESS BY INDEX ROWID BATCHED| CUSTOMERS            |33|6237|  10(0)|00:00:01|
|*2|  INDEX SKIP SCAN                   | CUST_GENDER_EMAIL_IX |33|    |   4(0)|00:00:01|
-----------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("CUST_EMAIL"='Abbey@company.example.com')
       filter("CUST_EMAIL"='Abbey@company.example.com')



「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论