[英]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.