【问题标题】:optimise query postgressql优化查询postgresql
【发布时间】:2022-01-12 08:57:01
【问题描述】:

我的数据库有一个很长的查询:

explain 
SELECT DISTINCT C.* , 
       F.vp_booking_id , 
       F.provider_id , 
       F.campaign_code , 
       F.external_key , 
       F.total_price ,
       CASE 
          WHEN limonetik IS NULL OR limonetik != limonetix THEN NULL 
          ELSE limonetix 
       END AS limonetix  , 
       F.cancelled , F.eos_revenue 
FROM th_flow.cancellations_big_file C 
  LEFT JOIN ( 
    SELECT BHF.vp_booking_id , 
           BHF.provider_id , 
           BHF.campaign_code , 
           REPLACE(BHF.external_key, ' ', '') AS external_key , 
           BHF.total_price , 
           P.external_key AS limonetix ,
           coalesce(is_canceled_override, is_canceled) AS cancelled , 
           eos_revenue 
    FROM th_flow.booking_header_finances BHF , 
         th_flow.booking_headers BH , 
         th_flow.bookings B , 
         th_flow.payments P
    WHERE BHF.vp_booking_id = BH.vp_booking_id 
      AND removed = false 
      AND B.vp_booking_id = BHF.vp_booking_id 
      AND P.booking_id = B.booking_id 
      AND BHF.campaign_code NOT LIKE '%PFS%' 
  ) AS F
    ON (    C.external_key = F.external_key 
         OR (C.limonetik = F.limonetix AND C.limonetik IS NOT NULL AND amount = total_price) 
         OR C.new_external_key = F.external_key 
       )
WHERE C.external_key >= '5' AND C.external_key < 'A')

我有这个执行计划:

 "Unique  (cost=268324282.90..268353233.54 rows=772017 width=169)"
    "  ->  Sort  (cost=268324282.90..268326212.94 rows=772017 width=169)"
    "        Sort Key: c.excel_id, c.campaign_code, c.external_key, c.new_external_key, c.amount, c.limonetik, bhf.vp_booking_id, bhf.provider_id, bhf.campaign_code, 

(replace((bhf.external_key)::text, ' '::text, ''::text)), bhf.total_price, (CASE WHEN ((c.limonetik IS NULL) OR ((c.limonetik)::text <> (p.external_key)::text)) THEN NULL::character varying ELSE p.external_key END), (COALESCE(bhf.is_canceled_override, bhf.is_canceled)), bhf.eos_revenue"
    "        ->  Nested Loop Left Join  (cost=417158.28..268182814.80 rows=772017 width=169)"
    "              Join Filter: (((c.external_key)::text = replace((bhf.external_key)::text, ' '::text, ''::text)) OR (((c.limonetik)::text = (p.external_key)::text) AND (c.limonetik IS NOT NULL) AND (c.amount = bhf.total_price)) OR ((c.new_external_key)::text = replace((bhf.external_key)::text, ' '::text, ''::text)))"
    "              ->  Bitmap Heap Scan on cancellations_big_file c  (cost=119.40..1232.64 rows=3816 width=75)"
    "                    Recheck Cond: (((external_key)::text >= '5'::text) AND ((external_key)::text < 'A'::text))"
    "                    ->  Bitmap Index Scan on ""external_key _index""  (cost=0.00..118.45 rows=3816 width=0)"
    "                          Index Cond: (((external_key)::text >= '5'::text) AND ((external_key)::text < 'A'::text))"
    "              ->  Materialize  (cost=417038.88..605740.02 rows=1881727 width=55)"
    "                    ->  Hash Join  (cost=417038.88..577954.38 rows=1881727 width=55)"
    "                          Hash Cond: (bh.vp_booking_id = bhf.vp_booking_id)"
    "                          ->  Hash Join  (cost=264434.69..384907.04 rows=1984817 width=20)"
    "                                Hash Cond: (b.vp_booking_id = bh.vp_booking_id)"
    "                                ->  Hash Join  (cost=203870.61..293163.88 rows=2092218 width=16)"
    "                                      Hash Cond: (p.booking_id = b.booking_id)"
    "                                      ->  Seq Scan on payments p  (cost=0.00..50528.18 rows=2092218 width=12)"
    "                                      ->  Hash  (cost=158157.05..158157.05 rows=2629805 width=12)"
    "                                            ->  Seq Scan on bookings b  (cost=0.00..158157.05 rows=2629805 width=12)"
    "                                ->  Hash  (cost=38493.44..38493.44 rows=1345251 width=4)"
    "                                      ->  Seq Scan on booking_headers bh  (cost=0.00..38493.44 rows=1345251 width=4)"
    "                                            Filter: (NOT removed)"
    "                          ->  Hash  (cost=123603.04..123603.04 rows=1362252 width=47)"
    "                                ->  Seq Scan on booking_header_finances bhf  (cost=0.00..123603.04 rows=1362252 width=47)"
    "                                      Filter: ((campaign_code)::text !~~ '%PFS%'::text)"

你知道我该如何分析它并优化这个查询需要太长时间来执行

非常感谢

【问题讨论】:

  • 至少非常,您应该正确格式化您的查询,以便我们可以阅读它。就目前而言,您的问题是“为什么这段代码不起作用”。
  • 请使用 EXPLAIN(ANALYZE, VERBOSE, BUFFERS) 获取查询计划,以及每一步花费的时间。

标签: sql postgresql sql-execution-plan


【解决方案1】:

像这样重写你的子查询:

    SELECT BHF.vp_booking_id , 
           BHF.provider_id , 
           BHF.campaign_code , 
           REPLACE(BHF.external_key, ' ', '') AS external_key , 
           BHF.total_price , 
           P.external_key AS limonetix ,
           coalesce(is_canceled_override, is_canceled) AS cancelled , 
           eos_revenue 
    FROM th_flow.booking_header_finances BHF
   INNER JOIN th_flow.booking_headers BH
      ON BH.vp_booking_id = BHF.vp_booking_id
   INNER JOIN th_flow.bookings B
      ON B.vp_booking_id = BHF.vp_booking_id
   INNER JOIN th_flow.payments P
      ON P.booking_id = B.booking_id
    WHERE removed = false
      AND BHF.campaign_code NOT LIKE '%PFS%'

在执行计划中,对booking_header_financesbooking_headers有两次顺序扫描。如果您在这些列上创建两个索引,它们将更快地被索引扫描替换。

【讨论】:

    猜你喜欢
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 2018-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多