我最近遇到过在oracle中执行大型查询的功能,其中更改一件事导致查询过去需要花费10分钟花费3个小时。
简单总结一下,我在数据库中存储了很多坐标,每个坐标都有一个概率。然后我想把这些坐标“装”到50米的箱子里(基本上将坐标向下舍入到最接近的50米)并总结概率。
要做到这一点,查询的一部分是'选择x,y,总和(概率)来自......分组x,y'
最初我存储了大量的点数,概率为0.1,查询运行得相当不错,每个点大约需要10分钟。
然后我要求改变计算概率以调整分布的方式,因此它们不是全部为0.1,而是不同的值(例如0.03,0.06,0.12,0.3,0.12,0.06,0.03)。运行完全相同的查询会导致查询大约3个小时。
更改回所有0.1会使查询回到10分钟。
查看系统的查询计划和性能,看起来问题是“哈希组”功能旨在加速oracle中的分组。我猜测它是为每个唯一的x,y,概率值创建哈希条目,然后为每个唯一的x,y值求和概率。</ p>
任何人都可以更好地解释这种行为吗?
其他信息
感谢答案。他们允许我验证发生了什么。我目前正在运行查询,v $ sql_workarea_active的tempseg_size目前为7502561280并且正在快速增长。
鉴于我运行的开发服务器只有8GB的ram,看起来查询需要使用临时表。
我已经设法通过更改查询类型和预先计算某些信息来解决此问题。
答案 0 :(得分:3)
散列组(以及散列连接,以及其他操作,例如排序等)可以使用最佳(即内存中),一次通过或多次通过方法。最后两种方法使用TEMP存储,因此速度要慢得多。
通过增加可能的项目数量,您可能已经超过了为此类操作保留的内存中的项目数。
在查询运行时尝试查看v $ sql_workarea_active,看看是否是这种情况。或者查看v $ sql_workarea以获取历史信息。它还可以指示操作需要多少内存和/或临时空间。
如果结果是实际问题 - 尝试增加pga_aggregate_target初始化参数,如果可能的话。可用于优化散列/排序操作的内存量通常约为pga_aggregate_target的5%。
有关详细信息,请参阅Performance Tuning Guide。
答案 1 :(得分:3)
“'猜测它正在为每个唯一的x,y,概率值创建哈希条目,然后为每个唯一的x,y值求和概率” - 几乎可以肯定,因为这是查询所需的。
您可以使用解释计划检查查询是否需要临时dfisk空间来完成排序或分组(等)。
explain plan for
select x,y,sum(probability) from .... group by x,y
/
select * from table(dbms_xplan.display)
/
如果优化器可以从统计数据中正确推导出x和y组合的近似唯一数量,那么很有可能在第二个查询的输出的TempSpc列中它将显示多少磁盘空间(如果任何)将被要求完成查询(没有列=没有磁盘空间要求)。
这里有太多信息:http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_xplan.htm#i999234
如果临时空间使用率高,那么就像CaptP所说的那样,可能是时候进行一些内存调整了。在执行大量排序和聚合的数据库上,通常指定比SGA目标更高的PGA目标。
答案 2 :(得分:0)
您的 PGA_AGGREGATE_TARGET 是否有机会设置为零? HASH GROUPBY本身不太可能造成这个问题,它可能是它之前或之后的事情。将您的 OPTIMIZER_FEATURES_ENABLE 降级到10.1.0.4并重新运行查询 - 您将看到现在您将获得一个SORT GROUPBY,除非您设置了PGA大小,否则HACK GROUPBY几乎总是会超越它到MANUAL并且您的哈希工作区域尺寸过小。