索引可以与oracle中的group函数一起使用吗?
我正在运行以下查询。
SELECT Table_1.Field_1,
Table_1.Field_2,
SUM(Table_1.Field_5) BALANCE_AMOUNT
FROM Table_1, Table_2
WHERE Table_1.Field_3 NOT IN (1, 3)
AND Table_2.Field_2 <> 2
AND Table_2.Field_3 = 'Y'
AND Table_1.Field_1 = Table_2.Field_1
AND Table_1.Field_4 = '31-oct-2011'
GROUP BY Table_1.Field_1, Table_1.Field_2;
我已为 Table_1
的列 (Field_1,Field_2,Field_3,Field_4)
创建索引,但该索引未使用。
如果我从 select 子句中删除 SUM(Table_1.Field_5)
,则将使用索引。
我很困惑优化器是否没有使用该索引或其因为我在查询中使用的 SUM()
函数。
请分享您对此的解释。
I am running following query.
SELECT Table_1.Field_1,
Table_1.Field_2,
SUM(Table_1.Field_5) BALANCE_AMOUNT
FROM Table_1, Table_2
WHERE Table_1.Field_3 NOT IN (1, 3)
AND Table_2.Field_2 <> 2
AND Table_2.Field_3 = 'Y'
AND Table_1.Field_1 = Table_2.Field_1
AND Table_1.Field_4 = '31-oct-2011'
GROUP BY Table_1.Field_1, Table_1.Field_2;
I have created index for columns (Field_1,Field_2,Field_3,Field_4)
of Table_1
but the index is not getting used.
If I remove the SUM(Table_1.Field_5)
from select clause then index is getting used.
I am confused if optimizer is not using this index or its because of SUM()
function I have used in query.
Please share your explaination on the same.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您删除 SUM 时,您还会从查询中删除
field_5
。然后可以在索引中找到回答查询所需的所有数据,这可能比扫描表更快。如果您将field_5
添加到索引,则使用 SUM 的查询可能会使用该索引。When you remove the SUM you also remove
field_5
from the query. All the data needed to answer the query can then be found in the index, which may be quicker than scanning the table. If you addedfield_5
to the index the query with SUM might use the index.如果您的查询返回大部分表行,Oracle 可能会认为执行全表扫描比在索引和表堆之间“跳跃”(以获取
Table_1.Field_5
中的值)更便宜)。尝试将
Table_1.Field_5
添加到索引(从而用索引覆盖整个查询),看看这是否有帮助。请参阅仅索引扫描:避免表访问< /a> 使用卢克索引对正在发生的事情进行概念性解释。
If your query is returning the large percentage of table's rows, Oracle may decide that doing a full table scan is cheaper than "hopping" between the index and the table's heap (to get the values in
Table_1.Field_5
).Try adding
Table_1.Field_5
to the index (thus covering the whole query with the index) and see if this helps.See the Index-Only Scan: Avoiding Table Access at Use The Index Luke for conceptual explanation of what is going on.
正如您所提到的,求和函数的存在会导致索引被忽略。
有基于函数的索引:
然而,与所有基于函数的索引有他们的限制:
As you mentioned, the presence of the summation function results in the the Index being overlooked.
There are function based indexes:
However, as with all, function based indexes have their restrictions:
虽然我在这里看到了一些很好的答案,但遗漏了几个重要的点 -
说在 select 子句中使用 SUM(Table_1.Field_5) 会导致索引不被正确使用。您在
(Field_1,Field_2,Field_3,Field_4)
上的索引仍然可以使用。但是你的索引和sql查询有问题。由于您的索引仅位于
(Field_1,Field_2,Field_3,Field_4)
上,即使您的索引被使用,数据库也必须访问实际的表行以获取 Field_5 来应用过滤器。现在它完全取决于sql优化器制定的执行计划哪一个是具有成本效益的。如果 SQL 优化器发现全表扫描的成本低于使用索引的成本,它将忽略索引。这么说,我现在将告诉您索引可能存在的问题 -(Field_4,Field_1,Field_2,Field_3)
那么它会更快,因为您在 Field_4 -Table_1.Field_4 = '31-oct-2011' 上具有相等性
。想想看,这是 -Table_1.Field_4 = '31-oct-2011'
将为您提供更少的选项来选择最终结果Table_1.Field_3 NOT IN (1, 3)
代码>.由于您正在进行联接,情况可能会发生变化。最好查看执行计划并相应地设计索引/sql。Though I see some good answers here couple of important points are being missed -
Saying that having SUM(Table_1.Field_5) in select clause causes index not to be used in not correct. Your index on
(Field_1,Field_2,Field_3,Field_4)
can still be used. But there are problems with your index and sql query.Since your index is only on
(Field_1,Field_2,Field_3,Field_4)
even if your index gets used DB will have to access the actual table row to fetch Field_5 for applying filter. Now it completely depends on the execution plan charted out of sql optimizer which one is cost effective. If SQL optimizer figures out thatfull table scan
has less cost than using index it will ignore the index. Saying so I will now tell you probable problems with your index -(Field_4,Field_1,Field_2,Field_3)
then it will be quicker since you have equality on Field_4 -Table_1.Field_4 = '31-oct-2011'
. Think of it this was -Table_1.Field_4 = '31-oct-2011'
will give you less options to choose final result from thenTable_1.Field_3 NOT IN (1, 3)
. Things might change since you are doing a join. It's always best to see the execution plan and design your index/sql accordingly.