PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Bagaimana menyederhanakan kueri pemilihan yang berisi banyak pilihan dalam dan meningkatkan kinerja di PostgreSQL

Pengoptimalan :

  1. Dapatkan semua perhitungan agregat dalam satu pilihan - kelompokkan berdasarkan kueri.
  2. Ganti subpilihan dengan gabungan kiri
  3. Pembatasan tambahan dalam kueri dalam berdasarkan kondisi luar.

Dapatkan ini seperti ini:

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

Hasil saya dengan kueri ini:

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 varian asli:

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

Ukuran untuk pengurutan dan jumlah baris masih sama seperti yang seharusnya...

Tindakan berdasarkan data sampel Anda PG 9.3



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara terbaik untuk memilih baris acak PostgreSQL

  2. sifat `diesel::Expression` tidak diterapkan untuk `bigdecimal::BigDecimal`

  3. cara menghindari kolom di klausa 'di mana' jika parameter 'TIDAK LULUS' postgresql

  4. SqlAlchemy(Flask+Postgres):Bagaimana cara memperbarui hanya atribut tertentu dari bidang json?

  5. Nilai kolom PostgreSQL harus berurutan