提高Oracle中SUM对大表的SQL查询处理性能

问题描述 投票:0回答:2

我有一个包含大约 10 亿行和 50 列的表 我有一个这样的查询,但由于包含大量 SUM 函数,处理时间非常慢,甚至没有响应。该查询用于 Oracle Analytics 中的直接数据库查询。

删除所有SUM和GROUP BY后,返回100万行结果大约需要1分钟。添加所有 SUM 和 GROUP BY 后,行数变为大约 5k。
由于我需要在 Excel 中使用它进行进一步分析,因此我必须尽可能少地保留输出行,以使其数据大小保持较小并且处理时间不会太慢。

Select Col_1,
       Col_2,
       ...,
       Col_10,
       SUM(CASE WHEN col_5 = 1 and Col_6 = a then AMOUNT ELSE 0 END) as AMT_1,
       SUM(CASE WHEN col_5 = 2 and Col_6 = b then AMOUNT ELSE 0 END) as AMT_2,
       ...
       SUM(CASE WHEN col_5 = 6 and Col_6 = d then AMOUNT ELSE 0 END) as AMT_24
from table_a 
where col_1 = 1
      col_5 in (1,2,3,4,5,6)
      col_6 in (a,b,c,d)
Group by Col_1, Col_2,...,Col_10
     

我尝试使用 EXPLAIN 获取查询计划或通过 CREATE INDEX 添加索引,但不幸的是它们都不支持。确认系统中可以使用SELECT语句或WITH子句。而且我没有其他应用程序或系统可以访问我需要的同一数据库。 我可以做什么来优化性能?

oracle group-by sum
2个回答
0
投票

我可以建议您的一件事是在查询中使用 Between 运算符而不是 In 谓词。这肯定会提高查询的性能 -

Select Col_1,
       Col_2,
       ...,
       Col_10,
       SUM(CASE WHEN col_5 = 1 and Col_6 = a then AMOUNT ELSE 0 END) as AMT_1,
       SUM(CASE WHEN col_5 = 2 and Col_6 = b then AMOUNT ELSE 0 END) as AMT_2,
       ...
       SUM(CASE WHEN col_5 = 6 and Col_6 = d then AMOUNT ELSE 0 END) as AMT_24
from table_a 
where col_1 = 1
  AND col_5 BETWEEN 1 AND 6
  AND col_6 BETWEEN a AND d
Group by Col_1, Col_2,...,Col_10

0
投票

您绝对不想为此使用索引。以下是一些需要检查的事项:

  1. 您使用并行性(PQ)吗?拥有 10 亿行,您将需要健康的 PX 从站数量。假设您的数据库服务器有足够的 CPU,请尝试使用以下提示:

SELECT /*+ parallel(16) */ col_1, ....

  1. 确保您确实获得了请求的并行从站。检查

    gv$session
    并查看您的 P0** 进程数是否是 DOP 请求的两倍。如果没有,请询问您的 DBA 是否由于某种原因而被降级。仅仅因为您获得了并行计划并不意味着您将在执行时获得您想要的实际并行从属设备。

  2. 检查解释计划并确保它正在执行全表扫描。您不希望在这里使用索引。如果您看到正在使用索引,请强制执行完整扫描并提示:

    SELECT /*+ parallel(16) full(table_a) */

  3. 如果表已分区,您可以在分区键上添加谓词来删除不需要的分区吗?

  4. 询问您的 DBA 或者您是否可以自行查询

    v$pgastat
    并检查
    global memory bound
    的值。小于1G吗?如果是这样,请让您的 DBA 提高
    pga_aggregate_target
    (以及限制,如果设置且不够高),直到全局内存限制显示其最大可能值 1G。这将确保您在工作区中使用临时空间之前获得分配给这些聚合所需的尽可能多的内存。只需确保数据库主机上有足够的可用内存或操作系统文件缓存(可释放)。这样做的作用是减少临时表空间 I/O 所花费的时间,并允许在物理内存中进行哈希或排序聚合。或者更确切地说,允许更多的事情发生在记忆中。无论如何,有 10 亿行的数据很可能会溢出到磁盘上,但您希望尽可能慷慨。

  5. 最后,如果以上方法都不适合您,请为您的 sql_id 生成 SQL Monitor 报告并与我们分享。

© www.soinside.com 2019 - 2024. All rights reserved.