以下是我的select query
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,
CASE WHEN EXISTS(
SELECT gtab10.Productid FROM gtab10 INNER JOIN gtab09 ON gtab09.TranId =
gtab10.TranId WHERE gtab10.Productid = gtab04.Productid AND
gtab10.BatchId = gtab05.BatchId AND gtab09.acyrid = 7 limit 1) THEN 1 ELSE 0 END
AS
StkEntered,
(SELECT SUM(gtab10.qty) FROM gtab10 INNER JOIN gtab09 ON gtab10.TranId =
gtab09.TranId WHERE gtab10.Productid = gtab04.Productid AND
gtab10.BatchId = gtab05.BatchId AND gtab09.vrid = 6 AND gtab09.acyrid = 7)
+
(SELECT SUM(gtab10.qty) FROM gtab10 INNER JOIN gtab09 ON gtab10.TranId =
gtab09.TranId WHERE gtab10.Productid = gtab04.Productid AND
gtab10.BatchId = gtab05.BatchId AND gtab09.vrid in (10,11,23,42,35) AND
gtab09.trdate < Cast('2014-06-01' AS timestamp) AND gtab09.acyrid = 7)
AS
OpeningInQty
(SELECT SUM(gtab10.qty)FROM gtab10 INNER JOIN gtab09 ON gtab10.TranId =
gtab09.TranId WHERE gtab04.Productid = gtab10.Productid AND
gtab10.BatchId = gtab05.BatchId AND gtab09.vrid in( 12,32,33,44 ,45 ,46, 47 ,48 ,
49,18 , 34 ,25,27 ,15,26,24 , 43 ,36) AND gtab09.trdate < Cast('2014-06-01' AS
timestamp) AND gtab09.acyrid = 7) 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,
(SELECT SUM(gtab10.qty) FROM gtab10 INNER JOIN gtab09 ON gtab10.TranId =
gtab09.TranId WHERE gtab04.Productid = gtab10.Productid AND
gtab10.BatchId = gtab05.BatchId AND gtab09.vrid in (12 ,32 ,33 ,44 ,45 ,46 ,47,48
,49) AND (gtab09.trdate BETWEEN '2014-05-01' AND '2014-05-31')
) AS
PrMthSaleQty,
(SELECT (SUM(gtab10.qty * gtab10.ptr) ) FROM gtab10 INNER JOIN gtab09 ON
gtab10.TranId = gtab09.TranId WHERE gtab04.Productid = gtab10.Productid AND
gtab10.BatchId = gtab05.BatchId AND gtab09.vrid in( 12, 32 , 33 , 44 ,45 ,46 , 47
,48 , 49) AND (FreeOrRpl = 0 OR FreeOrRpl = 2) AND (gtab09.trdate BETWEEN '2014-
05-01' AND '2014-05-31')
) 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,
(SELECT gtab09.TrDate FROM gtab09 INNER JOIN gtab10 ON gtab09.TranId
=gtab10.TranId
where gtab09.VrId in (12,32,33,44,45,46, 47,48,49) And
gtab10.ProductId =gtab04.ProductId order by TrDate desc limit 1) 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 WHERE (gtab04.Masked = False AND gtab04.Banned = false) AND
gtab04.patentid in (321, 313 , 267 , 431) ORDER BY Patent, gtab04.Product
EXPLAIN ANALYZE
正如您在上面的选择中看到的,我使用了很多内部选择,而将这些内部选择添加到主< em> select 整体性能会降低,需要花费很多时间才能执行。
我认为(不确定)我的选择查询计划 差。
请帮助改进Query
。
修改
答案 0 :(得分:2)
优化:
这样做:
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
我对此查询的结果:
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
与原始版本对比:
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
排序和行数的大小仍与...相同。
基于样本数据的测量PG 9.3
答案 1 :(得分:1)
以下是优化此查询的一些建议,因为我看到它没有运行它。
这是我的SQL版本,如果您与我分享QUERY PLAN,我将不胜感激。
SELECT * FROM (
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,
CASE WHEN EXISTS(
SELECT gtab10.Productid
FROM gtab10 INNER JOIN gtab09 ON gtab10.TranId = gtab09.TranId
WHERE gtab10.Productid = gtab04.Productid AND gtab10.BatchId = gtab05.BatchId
AND gtab09.acyrid = 7 limit 1) THEN 1 ELSE 0 END
AS
StkEntered,
(SELECT SUM(gtab10.qty)
FROM gtab10 INNER JOIN gtab09 ON gtab10.TranId = gtab09.TranId
WHERE gtab10.Productid = gtab04.Productid AND gtab10.BatchId = gtab05.BatchId
AND (gtab09.vrid = 6
OR (gtab09.vrid in (10, 11, 23, 42, 35) AND gtab09.trdate < Cast('2014-06-01' AS timestamp))
AND gtab09.acyrid = 7)
AS
OpeningInQty
(SELECT SUM(gtab10.qty)
FROM gtab10 INNER JOIN gtab09 ON gtab10.TranId = gtab09.TranId
WHERE gtab10.Productid = gtab04.Productid AND gtab10.BatchId = gtab05.BatchId
AND gtab09.vrid in ( 12, 32, 33, 44, 45, 46, 47, 48, 49, 18, 34, 25, 27, 15, 26, 24, 43, 36)
AND gtab09.trdate < Cast('2014-06-01' AS timestamp) AND gtab09.acyrid = 7)
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,
(SELECT SUM(gtab10.qty)
FROM gtab10 INNER JOIN gtab09 ON gtab10.TranId = gtab09.TranId
WHERE gtab10.Productid = gtab04.Productid AND gtab10.BatchId = gtab05.BatchId
AND gtab09.vrid in (12, 32, 33, 44, 45, 46, 47, 48, 49)
AND (gtab09.trdate BETWEEN '2014-05-01' AND '2014-05-31')
)
AS
PrMthSaleQty,
(SELECT SUM(gtab10.qty * gtab10.ptr)
FROM gtab10 INNER JOIN gtab09 ON gtab10.TranId = gtab09.TranId
WHERE gtab10.Productid = gtab04.Productid
AND gtab10.BatchId = gtab05.BatchId
AND gtab09.vrid in (12, 32, 33, 44, 45, 46, 47, 48, 49)
AND (gtab09.trdate BETWEEN '2014-05-01' AND '2014-05-31')
AND (FreeOrRpl IN (0, 2))
)
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,
(SELECT MAX(gtab09.TrDate) FROM gtab09 INNER JOIN gtab10 ON gtab09.TranId = gtab10.TranId
where gtab09.VrId in (12,32,33,44,45,46, 47,48,49) And gtab10.ProductId = gtab04.ProductId)
AS
LastSaleDate ,
GTAB05.BatchId,
0 AS FreeSaleQty,
0 AS ReplSaleQty
FROM gtab04
LEFT JOIN gtab05 ON gtab04.Productid = gtab05.Productid AND gtab04.patentid in (321, 313, 267, 431)
INNER JOIN gtab15 ON gtab04.TaxId = gtab15.TaxId
INNER JOIN gtab07 ON gtab04.Patentid = gtab07.Patentid
WHERE (gtab04.Masked = False AND gtab04.Banned = false)
) v
ORDER BY v.Patent, v.Product