0

我一直致力于优化登陆页面的许多 SQL 查询,其中查询根据用户选择拼凑在一起并发送到 DB2 数据库。一切都运行得很好,许多查询接近或不到一秒。作为性能测试,我们最近在测试数据库中加载了大量数据。一张表乘以大约 20 倍,从 40k 左右的记录增加到 750k 记录。我们希望粗略模拟一年左右会出现的数据量。从那以后,一些查询进行了调整,但特别是一组查询受到了严重的打击,即包含 75 万条记录的表。查询本身有许多连接,但我发现将其减少以在单个表上选择/过滤仍然需要 30 多秒。

查询本身从表中选择大约十几个列,并根据几个条件进行过滤。远程快速的唯一方法是将其完全削减并严格缩小过滤条件,以大大简化过滤或大幅减少行数。那样它会在几秒钟内执行,但是任何复杂程度的分层都会像疯了一样延迟执行。解释计划没有帮助。它显示的成本远低于运行时建议的成本,远低于 100k。有了这些数字,您预计它会在 2 秒内运行。

索引已经到位,但我开始怀疑一个糟糕的索引是否真的让它窒息。要了解查询结构...

SELECT 
--12 or so fields
FROM
TABLE A
--A few joins
WHERE
A.FIELD1 is not null
AND a.FIELD2 IN (:param) --max 2 values here
AND (a.FIELD3 BETWEEN :date1 AND date2
(OR A.FIELD3 < :date3 AND A.FIELD4 IN ('ONE','TWO')))

我已经修改并删除了 OR 子句中的位,这仅有助于非常简单的查询。否则运行时间仍然太长而无法产生影响。Runstats/分布式统计是准确的。桌子刚刚重组,没有任何帮助。我希望有人可以在这里提供一些指示。

更新:运行分布式统计。SYSIBM.SYSCOLDIST 和 SYSCAT.COLDIST 都显示了表 A 的当前数据。查询仍在可怕地运行,并且需要很长时间才能获取结果。可能会有更好的差异,但还不足以显着。值得注意的是,调整过滤器以返回一个小的结果集执行得非常快。更改过滤器以返回更大的过滤器需要永远获取行。一些简单的内部连接似乎不会破坏运行时,但是任何远程大或复杂的东西都会完全破坏它。这是唯一表现出这种行为的表。还有其他 270 万行的运行速度比这更快。

Aaaand 我想我找到了问题所在。事实证明,数据加载将这些日期置于一周的范围内,因此即使触及该范围也会使数据集达到数十万行。犯罪。是时候让脚本获取该范围内的日期并在一年的空间中以更好的分布更新行了……

Aaaand 这不完全是问题所在。在数据加载之前将该日期范围设置为较宽的区域会产生大约 4.5k 的结果,这很好,但仍然需要大约 9 秒,3.5 秒用于获取结果集。

4

2 回答 2

0

过时的统计数据通常是查询缓慢的原因,尤其是当缺少索引不是问题时。

具有“低”成本的解释计划也支持这一点。

而您刚刚插入大量数据的事实使这成为一个非常合理的原因。

于 2013-04-17T16:54:41.640 回答
0

您是否尝试过将其作为UNION?如果要显示任何重复项,可以使用 UNION ALL。

SELECT --12 or so fields
FROM TABLE A
--A few joins
WHERE A.FIELD1 is not null
AND a.FIELD2 IN (:param) --max 2 values here
AND a.FIELD3 BETWEEN :date1 AND date2
UNION
SELECT --12 or so fields
FROM TABLE A
--A few joins
WHERE A.FIELD1 is not null
AND a.FIELD2 IN (:param) --max 2 values here
AND A.FIELD3 < :date3 
AND A.FIELD4 IN ('ONE','TWO')

如果这不是更快,您可以发布您的解释计划吗?

于 2013-04-17T16:51:53.787 回答