不,这可能不正确。
如果您有一个大表,Oracle 可以更喜欢从索引而不是从表中派生字段,即使没有涵盖所有值的单个索引。
在我博客的最新文章中:
,有一个查询Oracle不使用全表扫描而是连接两个索引来获取列值:
SELECT l.id, l.value
FROM t_left l
WHERE NOT EXISTS
(
SELECT value
FROM t_right r
WHERE r.value = l.value
)
计划是:
SELECT STATEMENT
HASH JOIN ANTI
VIEW , 20090917_anti.index$_join$_001
HASH JOIN
INDEX FAST FULL SCAN, 20090917_anti.PK_LEFT_ID
INDEX FAST FULL SCAN, 20090917_anti.IX_LEFT_VALUE
INDEX FAST FULL SCAN, 20090917_anti.IX_RIGHT_VALUE
如您所见,这里的t_left 上没有TABLE SCAN。
相反,Oracle 获取 id 和 value 上的索引,将它们连接到 rowid 并从连接结果中获取 (id, value) 对。
现在,您的问题:
SELECT *
FROM some_table
WHERE field_one is not null and field_two = ?
GROUP BY
field_three, field_four, field_five
首先,它不会编译,因为您从带有GROUP BY 子句的表中选择*。
您需要将* 替换为基于分组列和非分组列聚合的表达式。
您很可能会从以下索引中受益:
CREATE INDEX ix_sometable_23451 ON some_table (field_two, field_three, field_four, field_five, field_one)
,因为它将包含在field_two 上进行过滤、在field_three, field_four, field_five 上排序(对GROUP BY 有用)并确保field_one 是NOT NULL 的所有内容。