连接中不使用唯一索引(覆盖 3 列)

Posted

技术标签:

【中文标题】连接中不使用唯一索引(覆盖 3 列)【英文标题】:Unique index (covering 3 columns) is not used in join 【发布时间】:2014-01-27 13:38:22 【问题描述】:

我有一个关于唯一索引的(非)使用的问题。我正在使用 Oracle 11g。

表 A: col1、col2、col3。 col1-col2-col3 三元组在表 A 中具有多列唯一索引。

表 B: colX. colX 是表 B 的主键。

我的查询是:

SELECT * FROM TABLE_A A
JOIN TABLE_B B ON A.col1 = B.colX
WHERE A.col2 = 10 and A.col3 = 20

当我查看 Toad 中的解释计划时,我看到“TABLE_A 中的每一行都已读取”。 (完全访问)。

但是,当我编写查询时:

SELECT * FROM TABLE_A A
WHERE A.col1 = 10 AND A.col2 = 20 AND A.col3 = 30

它使用唯一索引。

我也尝试过使用 IN,但在 IN 查询中也没有使用索引。有没有办法在这种连接查询中使用这个唯一索引?如果没有,您能否指出另一种提高此查询速度的方法?谢谢。

【问题讨论】:

en.wikipedia.org/wiki/Database_index#Column_order 了解composite index 唯一索引定义可以帮助我们帮助您。我猜想 col2 是在 col3 之前声明的,所以没有 col2 的查询被强制进入表扫描。如果您将更频繁地使用类似 1 的查询,则应考虑重新排序索引列。 如果 where 中的第一列与索引中的第一列匹配,则将使用索引(通常)。如果您想在第一个查询中创建索引,请创建 index (col2,col3) [at] ckuhn203:我尝试了 (col1,col2,col3) 和 (col2,col3,col1) 以及其他一些命令,但它仍然使用表扫描。 @Mihai: index(col2,col3) 有效。感谢您的回答。 【参考方案1】:

TABLE_A 上,创建一个仅包含col1 的索引(用于连接)和另一个仅包含col2col3 的索引(用于过滤谓词)。

查询优化器会将 JOIN 和过滤视为两个独立的操作。它不会使用带有col1 的索引作为过滤操作的第一列。

【讨论】:

以上是关于连接中不使用唯一索引(覆盖 3 列)的主要内容,如果未能解决你的问题,请参考以下文章

0001.索引

sqlite:唯一覆盖索引

名词解释与区分聚集索引非聚集索引主键索引唯一索引普通索引前缀索引单列索引组合索引全文索引覆盖索引

名词解释与区分聚集索引非聚集索引主键索引唯一索引普通索引前缀索引单列索引组合索引全文索引覆盖索引

MySQL外键+唯一索引

MYSQL中唯一约束和唯一索引的区别