如何改善以下查询的效果?目前需要35分钟。
-- Select
SELECT
RPT_FT_MD_FLOWS.FECDATA, RPT_FT_MC_CONTR.L2V,
RPT_FT_MD_FLOWS.CODCONT, SUM(RPT_FT_MD_FLOWS.IMPMOCMP)
FROM
RPT_FT_MD_FLOWS,
RPT_FT_MC_CONTR
WHERE
-- joins
RPT_FT_MD_FLOWS.IDGRUEMP = RPT_FT_MC_CONTR.IDGRUEMP AND
RPT_FT_MD_FLOWS.FECDATA = RPT_FT_MC_CONTR.FECDATA AND
RPT_FT_MD_FLOWS.CODCONT = RPT_FT_MC_CONTR.CODCONT AND
RPT_FT_MD_FLOWS.IDEMPR = RPT_FT_MC_CONTR.IDEMPR AND
RPT_FT_MD_FLOWS.IDCENT = RPT_FT_MC_CONTR.IDCENT AND
RPT_FT_MD_FLOWS.CODPROD = RPT_FT_MC_CONTR.CODPROD AND
RPT_FT_MD_FLOWS.IDCONTR = RPT_FT_MC_CONTR.IDCONTR AND
RPT_FT_MD_FLOWS.IDSCONTR = RPT_FT_MC_CONTR.IDSCONTR AND
-- filters
RPT_FT_MD_FLOWS.FECDATA = '31-May-2014' AND
RPT_FT_MD_FLOWS.IDGRUEMP = '0022' AND
RPT_FT_MD_FLOWS.ACUMTEMP = 'MTH' AND
RPT_FT_MD_FLOWS.IDESCENA = '01' AND
RPT_FT_MD_FLOWS.CODCONT='CCPP'
--group by
GROUP BY
RPT_FT_MD_FLOWS.FECDATA,
RPT_FT_MC_CONTR.L2V,
RPT_FT_MD_FLOWS.CODCONT
RPT_FT_MC_CONTR
:3900万行RPT_FT_MD_FLOWS
:1.45亿行以下是explain命令的结果:
解释命令
Execution Plan
----------------------------------------------------------
Plan hash value: 2459895390
------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 268 | 29212 | 30846 (8)| 00:09:16 | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10002 | 268 | 29212 | 30846 (8)| 00:09:16 | | | Q1,02 | P->S | QC (RAND) |
| 3 | HASH GROUP BY | | 268 | 29212 | 30846 (8)| 00:09:16 | | | Q1,02 | PCWP | |
| 4 | PX RECEIVE | | 268 | 29212 | 30846 (8)| 00:09:16 | | | Q1,02 | PCWP | |
| 5 | PX SEND HASH | :TQ10001 | 268 | 29212 | 30846 (8)| 00:09:16 | | | Q1,01 | P->P | HASH |
| 6 | HASH GROUP BY | | 268 | 29212 | 30846 (8)| 00:09:16 | | | Q1,01 | PCWP | |
|* 7 | HASH JOIN | | 39M| 4127M| 30586 (7)| 00:09:11 | | | Q1,01 | PCWP | |
| 8 | PX BLOCK ITERATOR | | 39M| 1893M| 10659 (4)| 00:03:12 | 1 | 16 | Q1,01 | PCWC | |
|* 9 | TABLE ACCESS FULL | RPT_FT_MC_CONTR | 39M| 1893M| 10659 (4)| 00:03:12 | 833 | 848 | Q1,01 | PCWP | |
| 10 | PX RECEIVE | | 145M| 8184M| 19806 (9)| 00:05:57 | | | Q1,01 | PCWP | |
| 11 | PX SEND BROADCAST LOCAL| :TQ10000 | 145M| 8184M| 19806 (9)| 00:05:57 | | | Q1,00 | P->P | BCST LOCAL |
| 12 | PX BLOCK ITERATOR | | 145M| 8184M| 19806 (9)| 00:05:57 | 66 | 66 | Q1,00 | PCWC | |
|* 13 | TABLE ACCESS FULL | RPT_FT_MD_FLOWS | 145M| 8184M| 19806 (9)| 00:05:57 | 66 | 66 | Q1,00 | PCWP | |
------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
7 - access("RPT_FT_MD_FLOWS"."CODCONT"="RPT_FT_MC_CONTR"."CODCONT" AND "RPT_FT_MD_FLOWS"."FECDATA"="RPT_FT_MC_CONTR"."FECDATA" AND
"RPT_FT_MD_FLOWS"."IDGRUEMP"="RPT_FT_MC_CONTR"."IDGRUEMP" AND "RPT_FT_MD_FLOWS"."IDEMPR"="RPT_FT_MC_CONTR"."IDEMPR" AND
"RPT_FT_MD_FLOWS"."IDCENT"="RPT_FT_MC_CONTR"."IDCENT" AND "RPT_FT_MD_FLOWS"."CODPROD"="RPT_FT_MC_CONTR"."CODPROD" AND
"RPT_FT_MD_FLOWS"."IDCONTR"="RPT_FT_MC_CONTR"."IDCONTR" AND "RPT_FT_MD_FLOWS"."IDSCONTR"="RPT_FT_MC_CONTR"."IDSCONTR")
9 - filter("RPT_FT_MC_CONTR"."IDGRUEMP"='0022' AND "RPT_FT_MC_CONTR"."FECDATA"=TO_DATE(' 2014-05-31 00:00:00', 'syyyy-mm-dd
hh24:mi:ss'))
13 - filter("RPT_FT_MD_FLOWS"."IDESCENA"='01' AND "RPT_FT_MD_FLOWS"."FECDATA"=TO_DATE(' 2014-05-31 00:00:00', 'syyyy-mm-dd
hh24:mi:ss') AND "RPT_FT_MD_FLOWS"."IDGRUEMP"='0022' AND "RPT_FT_MD_FLOWS"."ACUMTEMP"='MTH')
答案 0 :(得分:4)
好吧,由于某种原因,我将尝试帮助解决此问题。因此,我们首先将其清理干净,以便可以使用它。首先,我们将首先删除ancient join syntax。我们还会添加一些别名。别名就是当你给一个标题一个昵称,然后你可以在那里引用我们不会在任何地方重复使用重复的表名来混淆代码的地方。这给了我们这样的东西。
SELECT
F.FECDATA,
C.L2V,
F.CODCONT,
SUM(F.IMPMOCMP)
FROM RPT_FT_MD_FLOWS as F
INNER JOIN RPT_FT_MC_CONTR as C
ON F.IDGRUEMP = C.IDGRUEMP
AND F.FECDATA = C.FECDATA
AND F.CODCONT = C.CODCONT
AND F.IDEMPR = C.IDEMPR
AND F.IDCENT = C.IDCENT
AND F.CODPROD = C.CODPROD
AND F.IDCONTR = C.IDCONTR
AND F.IDSCONTR = C.IDSCONTR
WHERE F.FECDATA = '31-May-2014'
AND F.IDGRUEMP = '0022'
AND F.ACUMTEMP = 'MTH'
AND F.IDESCENA = '01'
AND F.CODCONT='CCPP'
GROUP BY
F.FECDATA,
C.L2V,
F.CODCONT
所以让我们从这些连接谓词开始。我知道你声称这些是业务规则,但这两个表连接在一起真的是必要的吗?如果它比你的桌子结构骨架。没有理由让9个连接谓词将2个表组合在一起。它们是否真正提高了查询的选择性?如果真的需要这个,那么你的表结构需要修复。
接下来你的表似乎没有利用任何索引。如果您还没有这个,那么您应该在这些表上使用某种聚簇索引来简化搜索。
您可能还想在此表中添加一些其他索引,以帮助减少扫描/搜索以获取结果所需的大量数据。您的查询没有必要连接所有1.84亿行以返回268行。
答案 1 :(得分:0)
您可能想要从开始重写查询