one*_*jig 29 sql oracle indexing plsql
您是否需要为Oracle数据库中的分组字段创建索引?
例如:
select *
from some_table
where field_one is not null and field_two = ?
group by field_three, field_four, field_five
Run Code Online (Sandbox Code Playgroud)
我正在测试我为上面创建的索引,此查询的唯一相关索引是为field_two创建的索引.在任何其他字段上创建的其他单字段或复合索引将不会用于上述查询.这听起来不错吗?
Eri*_*lje 16
它可能是正确的,但这取决于你有多少数据.通常我会为GROUP BY中使用的列创建索引,但在您的情况下,优化器可能已经决定在使用field_two索引之后返回的数据不足以证明使用GROUP的其他索引是合理的通过.
不,这可能是不正确的.
如果你有一个大表,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
)
Run Code Online (Sandbox Code Playgroud)
计划是:
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
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,有没有TABLE SCAN
在t_left
这里.
相反,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
Run Code Online (Sandbox Code Playgroud)
首先,它不会编译,因为您*
从带有GROUP BY
子句的表中进行选择.
您需要*
根据非分组列的分组列和聚合替换表达式.
您很可能会从以下索引中受益:
CREATE INDEX ix_sometable_23451 ON some_table (field_two, field_three, field_four, field_five, field_one)
Run Code Online (Sandbox Code Playgroud)
因为它将包含用于过滤field_two
,排序field_three, field_four, field_five
(有用GROUP BY
)和确保它的所有field_one
内容NOT NULL
.