SQL查询在获取结果集时花费了大量时间

时间:2013-04-17 16:47:20

标签: sql db2

我一直致力于为着陆页优化大量SQL查询,其中查询根据用户选择拼凑在一起并激发到DB2数据库。一切都运行良好,许多查询接近或低于一秒。作为性能测试,我们最近使用大量数据加载了测试数据库。一张表乘以约20倍,从40k左右的记录增加到750k记录。我们希望粗略模拟一年左右的数据量。有些查询已经被调整过了,但是特别是一组特别糟糕,这是一个有750k记录的表。查询本身有很多连接,但我发现将它剪切到单个表上的选择/过滤仍然需要30多秒。有时查询本身会花费很长时间,有时候查询会在几秒钟后运行,然后以非常缓慢的速度向上提取行数超过20秒。

查询本身从表中选择了大约十二列,并根据几个条件进行过滤。它远程快速的唯一方法是将其全部降低并严格缩小过滤标准,以大大简化过滤或大幅减少行数。它会以这种方式在几秒钟内执行,但是在任何程度的复杂性上进行分层都会像疯了一样延迟执行。解释计划没有帮助。它显示了远远低于运行时所表明的成本,远低于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我想我发现了这个问题。事实证明,dataload将这些日期放入一周的范围内,因此即使触摸该范围也会使数据集达到数十万行。 Criminy。是时候让脚本获取该范围内的日期并在一年的时间内更新分布更好的行......

Aaaand并不完全是问题所在。在数据加载产生大约4.5k结果之前将该日期范围设置为广泛区域,这很好,但它仍然需要大约9秒,花费3.5秒来获取结果集。

2 个答案:

答案 0 :(得分: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')

如果这不是更快,你可以发布EXPLAIN计划吗?

答案 1 :(得分:0)

过时的统计信息通常是查询速度慢的原因,尤其是当缺少索引不是问题时。

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

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