为啥 oracle 对此查询使用索引跳过扫描?

Posted

技术标签:

【中文标题】为啥 oracle 对此查询使用索引跳过扫描?【英文标题】:Why oracle uses index skip scan for this query?为什么 oracle 对此查询使用索引跳过扫描? 【发布时间】:2016-02-25 12:17:54 【问题描述】:

SQL只查询一张表,该表有1亿行。

SQL 在 where 子句中有三列,col_datecol_char1col_char2col_date 属于date 类型,但只有天部分,没有时间部分,比如'2016-02-25 00:00:00',这个列有大约1000个唯一值,这些值平均分布在表中的记录。 col_char1varchar2 类型,它有大约 30 个唯一值,并且这些值也均匀分布。 col_char2 也是 varchar2 类型,它有大约 20 个唯一值,并且这些值分布均匀。 where 子句类似于col_date >= to_date('2016-02-24 00:00:00') and col_char1 = 'VAL1' and col_char2 = 'VAL2'。查询结果约3000行。

我使用col_datecol_char1col_char2 创建了一个索引INDEX1,顺序为col_datecol_char1col_char2

执行计划是使用INDEX1 的索引跳过扫描。我不知道为什么它使用跳过扫描而不是范围扫描。我认为跳过扫描应该使这个查询非常慢,因为索引中的第一列 (col_date) 有很多不同的值。

【问题讨论】:

您的查询计划中的基数是否与实际数据匹配? ....统计数据正确吗? 【参考方案1】:

您问题中条件的最佳索引是(col_char1, col_char2, col_date) 上的复合索引(或者前两个键可以颠倒)。

如果你没有这个索引,但有类似的索引,那么我认为会使用跳过扫描。

【讨论】:

为什么索引中的col_date 列最后没有被跳过,该列的条件比其他两列过滤掉更多的行。谢谢 @roywang 。 . .因为您在其他两列上具有相等条件并且在日期上具有不等式。

以上是关于为啥 oracle 对此查询使用索引跳过扫描?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Oracle 在应该使用索引时使用全表扫描?

索引范围扫描 vs 索引跳过扫描 vs 索引快速全扫描

为啥此查询在 PostgreSQL 中不使用仅索引扫描?

为啥查询不使用Oracle中的索引

技术分享 为啥 SELECT 查询选择全表扫描,而不走索引?

一个Oracle添加索引造成其他用户对此表的查询权限丢失的案例