繁体   English   中英

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

[英]Postgres query taking long to execute

我正在使用 libpq 在 C++ 代码中连接 Postgres 服务器。 Postgres 服务器版本为 12.10

我的表模式定义如下

       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)

当我执行以下查询时,执行需要 1 - 2 毫秒。 时间作为参数提供给执行此查询的函数,它包含纪元秒和微秒。

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

此查询在同一客户端连接上每 30 秒执行一次(持续数周)。 此过程会运行数周,但有时同一查询开始需要超过 10 分钟。

如果我重新启动该过程,它会重新创建与服务器的连接,现在执行时间再次回落到 1-2 毫秒。 此问题是间歇性的,有时会在运行一周后触发,有时会在运行 2-3 周后触发。

我们每周日在表中添加一个新分区,并在新分区中写入新数据。

我不知道为什么性能不一致,有很多可能性我们无法通过提供的信息来区分。 例如,当性能发生变化时,计划是否会发生变化,或者相同的计划是否会变得更糟?

但是您的查询并不是为了最大限度地利用索引而编写的。 在我手中,它可以使用索引进行排序,但是它仍然需要读取并单独跳过 WHERE 子句失败的内容,直到找到第一个通过的内容。 而且由于分区,我认为它甚至比这更糟糕,它必须执行此读取和跳过操作,直到找到每个分区中通过的第一个。

你可以重写它来做一个元组比较,它可以使用索引来确定顺序和从哪里开始:

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

现在这也可能会降级,也可能不会降级,或者可能会降级但仍然如此之快,这无关紧要。

暂无
暂无

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

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