Optimierungen :
- Alle Aggregate in Einzelauswahl berechnen - nach Abfrage gruppieren.
- Subselects durch Left Join ersetzen
- Zusätzliche Einschränkung in der inneren Abfrage basierend auf äußeren Bedingungen.
Erhalten Sie dies als solches:
with gtab4_5 as (
select
gtab04.Productid, gtab05.BatchId
FROM
gtab04
LEFT JOIN gtab05
ON gtab04.Productid = gtab05.Productid
WHERE (gtab04.Masked = False AND gtab04.Banned = false)
AND gtab04.patentid in (321, 313 , 267 , 431)
)
SELECT
gtab04.Productid,
gtab04.Product,
gtab04.SaleUnit ,
gtab04.Packing,
gtab04.ConvFact,
gtab04.PTR,
gtab04.MRP,
gtab04.PRate,
gtab04.PTR1,
gtab04.PTR2,
gtab04.Location,
0 As ManufId,
gtab07.PatentId,
gtab07.Patent,
gtab07.PatentCd,
gtab15.TaxId,
gtab15.TaxName,
gtab15.TaxType,
gtab15.TaxRate,
gtab15.TxOMRP,
''::text As Manufacture,
stats_ags.StkEntered AS StkEntered,
stats_ags.OpeningInQty as OpeningInQty,
stats_ags.OpeningOutQty as OpeningOutQty,
0 AS PurchQty,
0 AS SRetQty,
0 AS PerInQty,
0 AS SaleQty,
0 AS StockInQty,
0 AS StockOutQty,
0 AS SaleAmt,
0 AS DamageQty,
0 AS PRetQty,
0 AS PerOutQty,
stats_ags.PrMthSaleQty as PrMthSaleQty,
stats_ags.PrMthSaleAmt as PrMthSaleAmt,
gtab04.LandCost,
gtab05.PTR AS BatchPTR,
(case when (
gtab05.Fqty - gtab05.FIQty)>0 then (gtab05.Fqty - gtab05.FIQty) else 0 end) as
IssdFreeQty,
gtab05.MRP AS BatchMRP,
gtab05.PRate AS BatchPRate,
gtab04.StdPack,
(date_part('day', (Select Min(Expiry) From gtab05 WHERE gtab05.Productid =
gtab04.Productid And gtab05.Qty > gtab05.IQty)-Cast('2014-06-20' AS
timestamp))) AS
ExpDys,
stats_ags.LastSaleDate as LastSaleDate ,
GTAB05.BatchId,
0 AS FreeSaleQty,
0 AS ReplSaleQty
FROM
gtab04
INNER JOIN gtab15
ON gtab04.TaxId = gtab15.TaxId
LEFT JOIN gtab05
ON gtab04.Productid = gtab05.Productid
INNER JOIN gtab07
ON gtab07.Patentid = gtab04.Patentid
left join (
SELECT gtab10_9.Productid, gtab10_9.BatchId,
max( case
when gtab10_9.acyrid = 7
then gtab10_9.Productid else null
end) as StkEntered,
SUM( case
when gtab10_9.acyrid = 7 and (
gtab10_9.vrid = 6
or (
gtab10_9.vrid in (10,11,23,42,35)
AND gtab10_9.trdate < Cast('2014-06-01' AS timestamp)
) )
then gtab10_9.qty else 0
end) as OpeningInQty,
SUM( case
when gtab10_9.acyrid = 7
and gtab10_9.vrid in( 12,32,33,44 ,45 ,46, 47 ,48 , 49,18 , 34 ,25,27 ,15,26,24 , 43 ,36)
AND gtab10_9.trdate < Cast('2014-06-01' AS timestamp)
then gtab10_9.qty else 0
end) as OpeningOutQty,
SUM( case
when gtab10_9.acyrid = 7
and gtab10_9.vrid in(12 ,32 ,33 ,44 ,45 ,46 ,47,48,49)
AND gtab10_9.trdate BETWEEN '2014-05-01' AND '2014-05-31'
then gtab10_9.qty else 0
end) as PrMthSaleQty,
SUM( case
when gtab10_9.acyrid = 7
and gtab10_9.vrid in( 12, 32 , 33 , 44 ,45 ,46 , 47,48 , 49)
and (gtab10_9.FreeOrRpl = 0 OR gtab10_9.FreeOrRpl = 2)
AND gtab10_9.trdate BETWEEN '2014-05-01' AND '2014-05-31'
then gtab10_9.qty * gtab10_9.ptr else 0
end) as PrMthSaleAmt,
MAX( case
when gtab10_9.acyrid = 7
and gtab10_9.VrId in (12,32,33,44,45,46, 47,48,49)
and (gtab10_9.FreeOrRpl = 0 OR gtab10_9.FreeOrRpl = 2)
then gtab10_9.TrDate else null
end) as LastSaleDate
FROM (
SELECT gtab10.*, gtab09.*
FROM gtab10
INNER JOIN gtab09 ON gtab09.TranId = gtab10.TranId
inner join gtab4_5 on gtab4_5.Productid = gtab10.Productid and gtab4_5.BatchId = gtab10.BatchId
) gtab10_9
group by gtab10_9.Productid, gtab10_9.BatchId
) stats_ags
on stats_ags.Productid = gtab04.Productid
and stats_ags.BatchId = gtab05.BatchId
WHERE (gtab04.Masked = False AND gtab04.Banned = false)
AND gtab04.patentid in (321, 313 , 267 , 431)
ORDER BY Patent, gtab04.Product
Meine Ergebnisse mit dieser Abfrage:
Sort (cost=82928.96..82931.84 rows=1152 width=306) (actual time=447.433..450.191 rows=2421 loops=1)
Sort Key: gtab07.patent, gtab04.product
Sort Method: external merge Disk: 680kB
Vs ursprüngliche Variante:
Sort (cost=2796544.62..2796547.50 rows=1152 width=278) (actual time=47865.883..47868.570 rows=2421 loops=1)
Sort Key: gtab07.patent, gtab04.product
Sort Method: external merge Disk: 680kB
Größe für Sortierung und Zeilenanzahl immer noch gleich wie angenommen...
Maßnahmen basierend auf Ihren Probendaten PG 9.3