索引可以与oracle中的group函数一起使用吗?

发布于 2024-12-10 16:36:08 字数 663 浏览 0 评论 0原文

我正在运行以下查询。

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

楠木可依 2024-12-17 16:36:08

当您删除 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 added field_5 to the index the query with SUM might use the index.

醉生梦死 2024-12-17 16:36:08

如果您的查询返回大部分表行,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.

念﹏祤嫣 2024-12-17 16:36:08

正如您所提到的,求和函数的存在会导致索引被忽略。

基于函数的索引

基于函数的索引包括由函数(例如 UPPER 函数)转换的列,或包含在表达式(例如 col1 + col2)中的列。

在转换后的列或表达式上定义基于函数的索引允许在 WHERE 子句或 ORDER BY 子句中使用该函数或表达式时使用该索引返回数据。因此,当频繁执行的 SQL 语句在 WHERE 或 ORDER BY 子句中包含转换列或表达式中的列时,基于函数的索引可能会很有用。

然而,与所有基于函数的索引有他们的限制:

基于函数的索引中的表达式不能包含任何聚合函数。表达式必须仅引用表中一行中的列。

As you mentioned, the presence of the summation function results in the the Index being overlooked.

There are function based indexes:

A function-based index includes columns that are either transformed by a function, such as the UPPER function, or included in an expression, such as col1 + col2.

Defining a function-based index on the transformed column or expression allows that data to be returned using the index when that function or expression is used in a WHERE clause or an ORDER BY clause. Therefore, a function-based index can be beneficial when frequently-executed SQL statements include transformed columns, or columns in expressions, in a WHERE or ORDER BY clause.

However, as with all, function based indexes have their restrictions:

Expressions in a function-based index cannot contain any aggregate functions. The expressions must reference only columns in a row in the table.

此岸叶落 2024-12-17 16:36:08

虽然我在这里看到了一些很好的答案,但遗漏了几个重要的点 -

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;

说在 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 优化器发现全表扫描的成本低于使用索引的成本,它将忽略索引。这么说,我现在将告诉您索引可能存在的问题 -

  1. 正如其他人所说,您可以简单地将 Field_5 添加到索引,这样就不需要单独的表访问。
  2. 索引的顺序对于性能非常重要。例如。在您的情况下,如果您将订单指定为 (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 -

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;

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 that full 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 -

  1. As others have states you could simply add Field_5 to the index so that there is no need for separate table access.
  2. Your order of index matters very much for performance. For eg. in your case if you give order as (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 then Table_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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文