簡體   English   中英

如何在 Postgres 中優化此查詢?

[英]How to optimize this query in Postgres?

我正在嘗試計算通過連接 3 個表中的值創建的“訪問”記錄。 我在下面有一個簡單的查詢,但在數據庫上需要將近 30 分鍾。 有沒有辦法進一步優化這個查詢?

select a."ClientID" as ClientID, b."ProviderID" as ProviderID, count(1) as VisitCount
from "Log" c
inner join "MessageDetail" b on c."MessageDetailID" = b."MessageDetailID"
inner join "Message" a on a."MessageID" = b."MessageID"
where a."CreatedUTCDate" >= NOW() - INTERVAL '1 HOUR'
group by a."ClientID", b."ProviderID"

示例結果

ClientID                                ProviderID   VisitCount
3245cf64-test-4d05-9d5d-345653566455    677777       1
3245cf64-test-4d05-9d5d-345653566455    677777       1
0284a326-test-4757-b00e-34563465dfgg    9999         5

解釋計划

GroupAggregate  (cost=6529150.62..6529160.28 rows=483 width=48)
  Group Key: a."ClientID", b."ProviderID"
  ->  Sort  (cost=6529150.62..6529151.83 rows=483 width=40)
        Sort Key: a."ClientID", b."ProviderID"
        ->  Nested Loop  (cost=1.00..6529129.09 rows=483 width=40)
              ->  Nested Loop  (cost=0.56..6509867.54 rows=3924 width=48)
                    ->  Seq Scan on "Message" a  (cost=0.00..6274917.96 rows=3089 width=44)
                          Filter: ("CreatedUTCDate" >= (now() - '01:00:00'::interval))
                    ->  Index Scan using "ix_MessageDetail_MessageId" on "MessageDetail" b  (cost=0.56..75.40 rows=66 width=20)
                          Index Cond: ("MessageID" = a."MessageID")
              ->  Index Only Scan using "ix_Log_MessageDetailId" on "Log" c  (cost=0.43..4.90 rows=1 width=8)
                    Index Cond: ("MessageDetailID" = b."MessageDetailID")

解釋分析計划

GroupAggregate  (cost=6529127.35..6529137.01 rows=483 width=48) (actual time=791639.382..791661.555 rows=118 loops=1)
  Group Key: a."ClientID", b."ProviderID"
  ->  Sort  (cost=6529127.35..6529128.56 rows=483 width=40) (actual time=791639.373..791649.235 rows=64412 loops=1)
        Sort Key: a."ClientID", b."ProviderID"
        Sort Method: external merge  Disk: 3400kB
        ->  Nested Loop  (cost=1.00..6529105.82 rows=483 width=40) (actual time=25178.920..791410.769 rows=64412 loops=1)
              ->  Nested Loop  (cost=0.56..6509844.55 rows=3924 width=48) (actual time=25178.874..790954.577 rows=65760 loops=1)
                    ->  Seq Scan on "Message" a  (cost=0.00..6274894.96 rows=3089 width=44) (actual time=25178.799..790477.178 rows=25121 loops=1)
                          Filter: ("CreatedUTCDate" >= (now() - '01:00:00'::interval))
                          Rows Removed by Filter: 30839080
                    ->  Index Scan using "ix_MessageDetail_MessageId" on "MessageDetail" b  (cost=0.56..75.40 rows=66 width=20) (actual time=0.009..0.016 rows=3 loops=25121)
                          Index Cond: ("MessageID" = a."MessageID")
              ->  Index Only Scan using "ix_Log_MessageDetailId" on "Log" c  (cost=0.43..4.90 rows=1 width=8) (actual time=0.005..0.006 rows=1 loops=65760)
                    Index Cond: ("MessageDetailID" = b."MessageDetailID")
                    Heap Fetches: 65590
Planning time: 38.501 ms
Execution time: 791662.728 ms

這部分執行計划

->  Seq Scan on "Message" a  (...) (actual time=25178.799..790477.178 rows=25121 loops=1)
      Filter: ("CreatedUTCDate" >= (now() - '01:00:00'::interval))
      Rows Removed by Filter: 30839080

證明"CreatedUTCDate"上的索引會大大加快這個查詢的速度:

  • 幾乎整個執行時間都花在了這個順序掃描中

  • 您掃描超過 3000 萬行以找到 25000 行,因此過濾條件具有高度選擇性

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM