加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

PostgreSQL通过查询优化顺序排列

发布时间:2020-12-13 15:53:47 所属栏目:百科 来源:网络整理
导读:我在这里遇到一个小问题. SELECT DISTINCT ON ("reporting_processedamazonsnapshot"."offer_id") *FROM "reporting_processedamazonsnapshot" INNER JOIN "offers_boooffer" ON ("reporting_processedamazonsnapshot"."offer_id" = "offers_boooffer"."id")
我在这里遇到一个小问题.

SELECT DISTINCT ON ("reporting_processedamazonsnapshot"."offer_id") *
FROM "reporting_processedamazonsnapshot" INNER JOIN 
     "offers_boooffer"
        ON ("reporting_processedamazonsnapshot"."offer_id" =
            "offers_boooffer"."id") INNER JOIN
     "offers_offersettings"
        ON ("offers_boooffer"."id" = "offers_offersettings"."offer_id")
WHERE "offers_offersettings"."account_id" = 20
ORDER BY "reporting_processedamazonsnapshot"."offer_id" ASC,"reporting_processedamazonsnapshot"."scraping_date" DESC

我在offer_id ASC上有一个名为latest_scraping的索引,scraping_date DESC但由于某种原因,PostgreSQL在使用索引后仍在进行排序,导致巨大的性能问题.

我不明白为什么它没有使用已经排序的数据而不是重做排序.我的索引错了吗?或者我应该尝试以另一种方式进行查询?

这是解释

enter image description here


与其实际数据

'Unique  (cost=21260.47..21263.06 rows=519 width=1288) (actual time=38053.685..38177.348 rows=1783 loops=1)'
'  ->  Sort  (cost=21260.47..21261.76 rows=519 width=1288) (actual time=38053.683..38161.478 rows=153095 loops=1)'
'        Sort Key: reporting_processedamazonsnapshot.offer_id,reporting_processedamazonsnapshot.scraping_date DESC'
'        Sort Method: external merge  Disk: 162088kB'
'        ->  Nested Loop  (cost=41.90..21237.06 rows=519 width=1288) (actual time=70.874..36148.348 rows=153095 loops=1)'
'              ->  Nested Loop  (cost=41.47..17547.90 rows=1627 width=8) (actual time=54.287..126.740 rows=1784 loops=1)'
'                    ->  Bitmap Heap Scan on offers_offersettings  (cost=41.04..4823.48 rows=1627 width=4) (actual time=52.532..84.102 rows=1784 loops=1)'
'                          Recheck Cond: (account_id = 20)'
'                          Heap Blocks: exact=38'
'                          ->  Bitmap Index Scan on offers_offersettings_account_id_fff7a8c0  (cost=0.00..40.63 rows=1627 width=0) (actual time=49.886..49.886 rows=4132 loops=1)'
'                                Index Cond: (account_id = 20)'
'                    ->  Index Only Scan using offers_boooffer_pkey on offers_boooffer  (cost=0.43..7.81 rows=1 width=4) (actual time=0.019..0.020 rows=1 loops=1784)'
'                          Index Cond: (id = offers_offersettings.offer_id)'
'                          Heap Fetches: 1784'
'              ->  Index Scan using latest_scraping on reporting_processedamazonsnapshot  (cost=0.43..1.69 rows=58 width=1288) (actual time=0.526..20.146 rows=86 loops=1784)'
'                    Index Cond: (offer_id = offers_boooffer.id)'
'Planning time: 187.133 ms'
'Execution time: 38195.266 ms'

解决方法

要使用索引来避免排序,PostgreSQL首先必须按索引顺序扫描所有“reporting_processedamazonsnapshot”,然后使用嵌套循环连接加入所有“offers_boooffer”(以便保留顺序),然??后加入所有“ offers_offersettings“,再次使用嵌套循环连接.

最后,所有与条件“offers_offersettings”不匹配的行.“account_id”= 20将被丢弃.

PostgreSQL认为 – 正确地说在我看来 – 使用条件尽可能地减少行数更有效率,然后使用最有效的join方法来连接表,然后对DISTINCT子句进行排序.

我想知道以下查询是否可能更快:

SELECT DISTINCT ON (q.offer_id) *
FROM offers_offersettings ofs
   JOIN offers_boooffer bo ON bo.id = ofs.offer_id
   CROSS JOIN LATERAL
      (SELECT *
       FROM reporting_processedamazonsnapshot r
       WHERE r.offer_id = bo.offer_id
       ORDER BY r.scraping_date DESC
       LIMIT 1) q
WHERE ofs.account_id = 20
ORDER BY q.offer_id ASC,q.scraping_date DESC;

执行计划将类似,只是必须从索引扫描更少的行,这将减少您最需要的执行时间.

如果要加快排序速度,请将该查询的work_mem增加到大约500MB(如果可以负担的话).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读