gpt4 book ai didi

postgresql - postgres如何调试为什么规划时间过长?

转载 作者:行者123 更新时间:2023-11-29 11:46:57 24 4
gpt4 key购买 nike

版本 - postgres 9.6。

question我不是很清楚我过去问过,那里已经有人回答了,所以我认为最好是发布新问题,提供更清晰的信息,并更具体地说明我的问题。

尝试将事件表与维度表连接起来。事件表是具有检查约束的每日分区(3k 子级)表。事件表有 72 列(我怀疑这是问题所在)。

我简化了查询以演示问题(实际上范围更广,我从两个表中查询字段)。

您可以看到对于这个简单的查询 - 计划 花费了将近 10 秒(我的问题是关于计划时间而不是执行时间)。如果我直接在子表上查询(请不要建议对范围内的所有子表使用联合)查询计划是几毫秒。

explain analyze select campaign_id ,  spent   as spent from events_daily r left join report_campaigns c on r.campaign_id = c.c_id  where  date >= '20170720' and date < '20170721' ;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop Left Join (cost=0.29..28.88 rows=2 width=26) (actual time=0.021..0.021 rows=0 loops=1)
-> Append (cost=0.00..12.25 rows=2 width=26) (actual time=0.003..0.003 rows=0 loops=1)
-> Seq Scan on events_daily r (cost=0.00..0.00 rows=1 width=26) (actual time=0.002..0.002 rows=0 loops=1)
Filter: ((date >= '2017-07-20 00:00:00'::timestamp without time zone) AND (date < '2017-07-21 00:00:00'::timestamp without time zone))
-> Seq Scan on events_daily_20170720 r_1 (cost=0.00..12.25 rows=1 width=26) (actual time=0.000..0.000 rows=0 loops=1)
Filter: ((date >= '2017-07-20 00:00:00'::timestamp without time zone) AND (date < '2017-07-21 00:00:00'::timestamp without time zone))
-> Index Only Scan using report_campaigns_campaign_idx on report_campaigns c (cost=0.29..8.31 rows=1 width=8) (never executed)
Index Cond: (c_id = r.campaign_id)
Heap Fetches: 0
Planning time: 8393.337 ms
Execution time: 0.132 ms
(11 rows)

explain analyze select campaign_id , spent as spent from events_daily_20170720 r left join report_campaigns c on r.campaign_id = c.c_id where date >= '20170720' and date < '20170721' ;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop Left Join (cost=0.29..20.57 rows=1 width=26) (actual time=0.008..0.008 rows=0 loops=1)
-> Seq Scan on events_daily_20170720 r (cost=0.00..12.25 rows=1 width=26) (actual time=0.007..0.007 rows=0 loops=1)
Filter: ((date >= '2017-07-20 00:00:00'::timestamp without time zone) AND (date < '2017-07-21 00:00:00'::timestamp without time zone))
-> Index Only Scan using report_campaigns_campaign_idx on report_campaigns c (cost=0.29..8.31 rows=1 width=8) (never executed)
Index Cond: (c_id = r.campaign_id)
Heap Fetches: 0
Planning time: 0.242 ms
Execution time: 0.059 ms


\d events_daily_20170720
date | timestamp without time zone |
Check constraints:
"events_daily_20170720_date_check" CHECK (date >= '2017-07-20 00:00:00'::timestamp without time zone AND date < '2017-07-21 00:00:00'::timestamp without time zone)
Inherits: events_daily

show constraint_exclusion;
constraint_exclusion
----------------------
on

当运行 ltrace 时,它​​似乎在每个字段上运行了数千次(暗示它在计划的所有分区表上运行):

strlen("process")                                                                                                                                                    = 7
memcpy(0x0b7aac10, "process", 8) = 0x0b7aac10
strlen("channel") = 7
memcpy(0x0b7aac68, "channel", 8) = 0x0b7aac68
strlen("deleted") = 7
memcpy(0x0b7aacc0, "deleted", 8) = 0x0b7aacc0
strlen("old_spent") = 9
memcpy(0x0b7aad18, "old_spent", 10)

最佳答案

问题是你的分区太多了。

作为the documentation警告:

All constraints on all partitions of the master table are examined during constraint exclusion, so large numbers of partitions are likely to increase query planning time considerably. Partitioning using these techniques will work well with up to perhaps a hundred partitions; don't try to use many thousands of partitions.

您应该尝试通过为每个分区使用更长的时间间隔来减少分区的数量。

或者,如果可能,您可以尝试更改应用程序代码以直接访问正确的分区,但这可能会很困难,并且它会消除分区应该带来的许多优势。

关于postgresql - postgres如何调试为什么规划时间过长?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45069283/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com