使用VBA中的SQL处理DB2数据库以生成一些自定义报告。我想出了下面的查询,但是花了45分钟才能运行80,000个结果......表BILLPRC在WHERE子句之前可能总共有两倍。只是想知道是否有更好的方法来编写查询来加快速度。这可能是一个非常模糊的问题,所以如果您需要更多信息,我可以进一步解释。
SELECT b.BLCO# || RIGHT('00000' || b.BLACCT, 5) Acct, b.BLRECT Type, b.BLREC# Record, i.INAME || ' ' || i.INAME2 Desc, b.BLPPGM# Promo, SUBSTR(b.BLPEFFD, 4, 2) || SUBSTR(b.BLPEFFD, 6, 2) || SUBSTR(b.BLPEFFD, 2, 2) Eff, SUBSTR(b.BLPENDD, 4, 2) || SUBSTR(b.BLPENDD, 6, 2) || SUBSTR(b.BLPENDD, 2, 2) Exp, CASE
WHEN (p.PPPRC1 = '0') THEN (p.PPPRC2)
WHEN (p.PPPRC1 != '0') THEN (p.PPPRC1) END Price,
CASE
WHEN (p.PPPRC1 = '0') THEN (p.PPCST2)
WHEN (p.PPPRC1 != '0') THEN (p.PPCST1) END Allow, i.ILASTC Cost
FROM QS36F.BILLPRC b
LEFT JOIN QS36F.PROMO p
ON b.BLREC# || b.BLPPGM# = p.PPREC || p.PPPGM#
LEFT JOIN QS36F.ITEM i
ON CASE
WHEN (b.BLRECT = 'I') AND (b.BLREC# = i.IMFGR || i.ICOLOR || i.IPATT) THEN 1
WHEN (b.BLRECT = 'P') AND (b.BLREC# = i.IPRCCD) THEN 1
END = 1
WHERE (b.BLPPGM# != '') AND (b.BLSTS != 'H')
ORDER BY (b.BLACCT)
我感觉没有给出记录和CASE的数量。
答案 0 :(得分:2)
通过在连接条件中重写WHERE谓词(b.BLPPGM# != '') AND (b.BLSTS != 'H')
,可能会获得更好的性能。
如果可能的话,尽量不要连接用于加入的字段。例如,而不是
LEFT JOIN QS36F.PROMO p
ON b.BLREC# || b.BLPPGM# = p.PPREC || p.PPPGM#
你可以说
LEFT JOIN QS36F.PROMO p
ON b.BLREC# = p.PPREC
and b.BLPPGM# = p.PPPGM#
或等效
LEFT JOIN QS36F.PROMO p
ON (b.BLREC#, b.BLPPGM#) = (p.PPREC, p.PPPGM#)
从WHERE子句中添加逻辑
LEFT JOIN QS36F.PROMO p
ON (b.BLREC#, b.BLPPGM#) = (p.PPREC, p.PPPGM#)
当然,这假设相应的字段是相同类型或兼容类型,理想情况下,字段的大小相同。 DB2通常可以自动将一种类型转换为另一种类型。字符串类型通常彼此兼容,而数字类型通常彼此兼容。
然后,最重要的是,确保您拥有正确的索引。 (我不太熟悉S / 36模式环境,但我假设您可以在其上创建索引。)索引也可以在派生列上构建,即。连接等表达式。
答案 1 :(得分:1)
出于报告目的,请使用materialized query table,除非您无法负担CPU时间。我知道它有点懒,但MQT适用于你可以获得每小时更新的结果,并且不想开始规范化和优化数据库。你有一个工作逻辑,你显然理解它,所以顺其自然。
答案 2 :(得分:1)
这看起来像是我的DB2 ....你可能想要适当地标记它
假设是,您是否使用过iNav的Run SQL脚本中的“Run& Explain”选项来查看数据库是否推荐了任何新索引?