简体   繁体   English

Postgres 查询需要很长时间才能执行

[英]Postgres query taking long to execute

I am using libpq to connect the Postgres server in c++ code.我正在使用 libpq 在 C++ 代码中连接 Postgres 服务器。 Postgres server version is 12.10 Postgres 服务器版本为 12.10

My table schema is defined below我的表模式定义如下

       Column        |   Type   | Collation | Nullable |  Default   | Storage  | Stats target | Description 
---------------------+----------+-----------+----------+------------+----------+--------------+-------------
 event_id            | bigint   |           | not null |            | plain    |              | 
 event_sec           | integer  |           | not null |            | plain    |              | 
 event_usec          | integer  |           | not null |            | plain    |              | 
 event_op            | smallint |           | not null |            | plain    |              | 
 rd                  | bigint   |           | not null |            | plain    |              | 
 addr                | bigint   |           | not null |            | plain    |              | 
 masklen             | bigint   |           | not null |            | plain    |              | 
 path_id             | bigint   |           |          |            | plain    |              | 
 attribs_tbl_last_id | bigint   |           | not null |            | plain    |              | 
 attribs_tbl_next_id | bigint   |           | not null |            | plain    |              | 
 bgp_id              | bigint   |           | not null |            | plain    |              | 
 last_lbl_stk        | bytea    |           | not null |            | extended |              | 
 next_lbl_stk        | bytea    |           | not null |            | extended |              | 
 last_state          | smallint |           |          |            | plain    |              | 
 next_state          | smallint |           |          |            | plain    |              | 
 pkey                | integer  |           | not null | 1654449420 | plain    |              | 
Partition key: LIST (pkey)
Indexes:
    "event_pkey" PRIMARY KEY, btree (event_id, pkey)
    "event_event_sec_event_usec_idx" btree (event_sec, event_usec)
Partitions: event_spl_1651768781 FOR VALUES IN (1651768781),
            event_spl_1652029140 FOR VALUES IN (1652029140),
            event_spl_1652633760 FOR VALUES IN (1652633760),
            event_spl_1653372439 FOR VALUES IN (1653372439),
            event_spl_1653786420 FOR VALUES IN (1653786420),
            event_spl_1654449420 FOR VALUES IN (1654449420)

When I execute the following query it takes 1 - 2 milliseconds to execute.当我执行以下查询时,执行需要 1 - 2 毫秒。 Time is provided as a parameter to function executing this query, it contains epoche seconds and microseconds.时间作为参数提供给执行此查询的函数,它包含纪元秒和微秒。

SELECT event_id FROM event WHERE (event_sec > time.seconds) OR ((event_sec=time.seconds) AND (event_usec>=time.useconds) ORDER BY event_sec, event_usec LIMIT 1

This query is executed every 30 seconds on the same client connection (Which is persistent for weeks).此查询在同一客户端连接上每 30 秒执行一次(持续数周)。 This process runs for weeks, but some time same query starts taking more than 10 minutes.此过程会运行数周,但有时同一查询开始需要超过 10 分钟。

If I restart the process it recreated connection with the server and now execution time again falls back to 1-2 milliseconds.如果我重新启动该过程,它会重新创建与服务器的连接,现在执行时间再次回落到 1-2 毫秒。 This issue is intermittent, sometimes it triggers after a week of running process and some time after 2 - 3 weeks of running process.此问题是间歇性的,有时会在运行一周后触发,有时会在运行 2-3 周后触发。

We add a new partition to table every Sunday and write new data in new partition.我们每周日在表中添加一个新分区,并在新分区中写入新数据。

I don't know why the performance is inconsistent, there are many possibilities we can't distinguish with the info provided.我不知道为什么性能不一致,有很多可能性我们无法通过提供的信息来区分。 Like, does the plan change when the performance changes, or does the same plan just perform worse?例如,当性能发生变化时,计划是否会发生变化,或者相同的计划是否会变得更糟?

But your query is not written to take maximal advantage of the index.但是您的查询并不是为了最大限度地利用索引而编写的。 In my hands it can use the index for ordering, but then it still needs to read and individually skip over things that fail the WHERE clause until it finds the first one which passes.在我手中,它可以使用索引进行排序,但是它仍然需要读取并单独跳过 WHERE 子句失败的内容,直到找到第一个通过的内容。 And due to partitioning, I think it is even worse than that, it has to do this read-and-skip until it finds the first one which passes in each partition.而且由于分区,我认为它甚至比这更糟糕,它必须执行此读取和跳过操作,直到找到每个分区中通过的第一个。

You could rewrite it to do a tuple comparison, which can use the index to determine both the order, and where to start:你可以重写它来做一个元组比较,它可以使用索引来确定顺序和从哪里开始:

SELECT event_id FROM event 
WHERE (event_sec,event_sec) >= (:seconds,:useconds) 
ORDER BY event_sec, event_usec LIMIT 1;  

Now this might also degrade, or might not, or maybe will degrade but still be so fast that it doesn't matter.现在这也可能会降级,也可能不会降级,或者可能会降级但仍然如此之快,这无关紧要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM