标签: postgresql

使用(时间戳、uuid)字段时键集分页不一致

我在我的 Postgres 数据库上使用 uuids 的键集分页方法,如本文所述:

但是,我注意到当我有两条日期相同的记录时,会从结果中跳过行。

例如,当我运行查询时:

SELECT id, created_at FROM collection
ORDER BY created_at DESC, id DESC
Run Code Online (Sandbox Code Playgroud)

我按照我的预期取回了记录,作为created_at主要顺序,然后id充当决胜局:

ID 创建时间
e327847a-7058-49cf-bd91-f562412aedd9 2022-05-23 23:07:22.592
d35c6bb8-06dd-4b86-b5c6-d123340520e2 2022-05-23 23:07:22.592
5167cf95-953f-4f7b-9881-03ef07adcf3c 2022-05-23 23:07:22.592
d14f48dc-df22-4e98-871a-a14a91e8e3c1 2022-05-23 23:07:21.592

但是,当我运行查询来分页时,例如:

SELECT id, created_at
FROM collection
WHERE (created_at, id) < ('2022-05-23 23:07:22.592','d35c6bb8-06dd-4b86-b5c6-d123340520e2')
ORDER BY created_at DESC, id DESC
LIMIT 3
Run Code Online (Sandbox Code Playgroud)

我希望取回最后两条记录,但我的结果集是

ID 创建时间
d14f48dc-df22-4e98-871a-a14a91e8e3c1 2022-05-23 23:07:21.592

我还尝试了查询的一些变体来尝试修复它,例如:

SELECT id, created_at
FROM collection
WHERE created_at < '2022-05-23 23:07:22.592' OR
     (created_at …
Run Code Online (Sandbox Code Playgroud)

postgresql query pagination

5
推荐指数
1
解决办法
1329
查看次数

Postgres 中的 EXISTS() 与 EXISTS() = TRUE

面临奇怪的行为EXISTS(也适用于NOT EXISTS)生成不同的执行计划

WHERE EXISTS(...)

EXPLAIN ANALYZE
SELECT * FROM books
WHERE EXISTS (SELECT 1 FROM authors WHERE id = books.author_id AND name LIKE 'asd%');

| QUERY PLAN                                                                                                     |
| -------------------------------------------------------------------------------------------------------------- |
| Hash Join  (cost=218.01..454.43 rows=56 width=40) (actual time=0.975..0.975 rows=0 loops=1)                    |
|   Hash Cond: (books.author_id = authors.id)                                                                    |
|   ->  Seq Scan on books  (cost=0.00..206.80 rows=11280 width=40) (actual time=0.010..0.010 rows=1 loops=1)     |
|   ->  Hash  (cost=217.35..217.35 rows=53 width=4) (actual time=0.943..0.943 rows=0 loops=1)                    |
|         Buckets: …
Run Code Online (Sandbox Code Playgroud)

postgresql exists postgresql-performance

5
推荐指数
1
解决办法
756
查看次数

PostgreSQL 可以使用索引来加速计数(不同)查询吗?

考虑以下示例:

CREATE TABLE test (
  id SERIAL,
  some_integer INT
);

INSERT INTO test (some_integer)
SELECT FLOOR(RANDOM()*100000) from generate_series(1,100000) s(i);

CREATE INDEX some_integer_idx ON test (some_integer);

EXPLAIN ANALYZE SELECT COUNT(DISTINCT some_integer) from test;
Run Code Online (Sandbox Code Playgroud)

它返回以下查询计划:

CREATE TABLE test (
  id SERIAL,
  some_integer INT
);

INSERT INTO test (some_integer)
SELECT FLOOR(RANDOM()*100000) from generate_series(1,100000) s(i);

CREATE INDEX some_integer_idx ON test (some_integer);

EXPLAIN ANALYZE SELECT COUNT(DISTINCT some_integer) from test;
Run Code Online (Sandbox Code Playgroud)

我很惊讶它仍然在测试中进行顺序扫描。简单地计算索引中的行数不是更快吗?

postgresql index count distinct

5
推荐指数
1
解决办法
1593
查看次数

这是 DELETE ... WHERE EXISTS 查询计划 O(n*2) 还是 O(n^2) ?

我正在尝试执行一项常见任务,从表中删除重复项,目的是添加唯一约束。

CREATE TABLE IF NOT EXISTS item_identifier (
    pk       BIGSERIAL PRIMARY KEY,
    prefix   INTEGER NOT NULL,
    suffix   VARCHAR(1024) NOT NULL
);
CREATE INDEX temp_prefix_suffix_idx ON item_identifier (prefix, suffix);
Run Code Online (Sandbox Code Playgroud)

我想使用常见查询删除重复项,该查询可以在本网站的许多答案中找到。我认为重复率大约为 1%,因此没有太多需要删除的内容。

提供索引纯粹是为了帮助重复数据删除,稍后将被删除。不过,如您所见,PostgreSQL 甚至没有使用它!

有 2,759,559,168 行。索引temp_prefix_suffix_idx本身约为 100 GB。花CREATE INDEX了 12 个小时所以我不指望DELETE会很快。但根据 10% 的样本集,我推断需要 20 小时,而实际上已经花了 40 小时。对于我的示例方法来说,它可能仍在误差范围内,但我担心由于它不使用索引,这将花费指数时间。

EXPLAINSeq Scan on item_identifier aSeq Scan on item_identifier b

EXPLAIN DELETE FROM item_identifier a
  WHERE EXISTS
    (SELECT FROM item_identifier b
       WHERE a.prefix …
Run Code Online (Sandbox Code Playgroud)

postgresql exists query-performance postgresql-performance

5
推荐指数
1
解决办法
425
查看次数

序列化异常是否只能通过 SUM/COUNT 实现?

我读过《深入了解 MySQL 和 PostgreSQL 中的隔离级别》和《读取现象》,尤其是“Postgres 中的序列化异常”部分。我想我已经理解了那里描述的问题,但是我很难判断它何时会在我的应用程序中发生。

是否只有使用 SUM/COUNT 这样的聚合函数才能在 Postgres 中获得序列化异常?如果不是,我还需要注意什么?

postgresql concurrency isolation-level

5
推荐指数
1
解决办法
1331
查看次数

在连接上生成连续数字

对于 JOIN 中的每个右侧行,我想创建一个序列号,每个左侧行从 1(或 0)开始。

例子:

create table persons (person_id int, person_name text);
create table places (place_id int, person_id int, place_name text);
insert into persons values (10, 'Aulus Agerius'), (20, 'Numerius Negidius');
insert into places values (10, 10, 'Anytown'), (20, 10, 'Timbuktu'), (30, 20, 'Podunk');
Run Code Online (Sandbox Code Playgroud)
select person_name, place_name
from persons join places using (person_id)
order by person_id, place_id;
Run Code Online (Sandbox Code Playgroud)

小提琴

期望的结果:

人名 地名 地点顺序
奥鲁斯·阿杰里乌斯 任意镇 1
奥鲁斯·阿杰里乌斯 廷巴克图 2
内吉迪乌斯 波敦克 1

例如,2 inplace_seq表示“这是为该人找到的第二个地方”。

如何创建place_seq专栏?

postgresql

5
推荐指数
1
解决办法
1147
查看次数

根据PostgreSQL/TimescaleDB中的关系数据选择遥测数据

我正在尝试解决一个特别困难的问题。我正在 SQL 表 (PostgreSQL) 中存储来自某些传感器的一些遥测数据,我想知道如何编写一个查询,该查询将使用来自其他两个表的关系信息对遥测数据进行分组。

我有一张表存储来自传感器的遥测数据。该表包含三个字段,一为时间戳,一为传感器ID,一为传感器当时的值。值列是一个递增计数(它只会增加,不会重置)

Sensor_Telemetry

时间戳 传感器 ID 价值
2022-01-01 00:00:00 5 3
2022-01-01 00:00:01 5 5
2022-01-01 00:00:02 5 6
... ... ...
2022-01-01 01:00:00 5 第675章

我有另一个表,用于存储传感器的状态(无论是静止还是运动)以及该传感器的特定状态的开始/结束日期:

状态

开始日期 结束日期 地位 传感器 ID
2022-01-01 00:00:00 2022-01-01 00:20:00 运动中 5
2022-01-01 00:20:00 2022-01-01 00:40:00 固定式 5
2022-01-01 00:40:00 2022-01-01 01:00:00 运动中 5
... ... ... ...

传感器位于特定位置。Sensor 表存储以下元数据:

传感器

传感器 ID 位置ID
5 16

在决赛表中,我有每个位置发生的变化。班次表是所有班次发生的列表,即在本例中,班次 A 定义为每天 00:00:00 到 00:30:00 之间发生,班次 B 定义为每天 00:30 …

postgresql join query aggregate timescaledb

5
推荐指数
1
解决办法
188
查看次数

在 RDS 上升级 postgres 时出现 pg_trgm 索引错误

我想将我的产品 Postgres RDS 数据库的主要版本从 11.16 升级到 12.11。我恢复了快照来进行试运行。当尝试修改AWS上的版本时,出现以下错误:

pg_restore: from TOC entry 5375; 1259 180582003 INDEX my_index my_database
pg_restore: error: could not execute query: ERROR: permission denied for schema publicf2iwen5v79e7a7ugjf2zdrpvhvpmr9bc
Command was:
-- For binary upgrade, must preserve pg_class oids
SELECT pg_catalog.binary_upgrade_set_next_index_pg_class_oid('180582003'::pg_catalog.oid);

CREATE INDEX "my_index" ON "publicf2iwen5v79e7a7ugjf2zdrpvhvpmr9bc"."my_table" USING "gin" ("upper"("my_column") "publicf2iwen5v79e7a7ugjf2zdrpvhvpmr9bc"."gin_trgm_ops");
Run Code Online (Sandbox Code Playgroud)

删除此索引和其他 3 个 trgm 索引后,升级工作正常。

我已经检查了扩展程序的所有者,它与其他扩展程序的所有者相同,并且我没有看到这些索引和其他索引之间有任何区别,除了它们来自pg_trgm

您知道如何解决这个问题吗?显然,我想避免在升级版本之前删除真实产品数据库上的这些索引。

从12升级到13时出现同样的问题

postgresql postgresql-extensions amazon-rds

5
推荐指数
0
解决办法
512
查看次数

优化 Postgresql 中的选择计数结果

我正在尝试优化包含超过 8000 万行的表。需要 20 多分钟才能获得行计数结果。我尝试过集群、vacuum full 和重新索引,但性能没有提高。为了改进数据查询和检索,我需要配置或调整什么?我在 Windows 2019 下使用 Postgresql 12。

更新信息:

  • 目前总行数约为 9200 万以上
  • 表列数 = 44
  • Explain query result using 'select count(*) from doc_details':  
        Finalize Aggregate  (cost=5554120.84..5554120.85 rows=1 width=8) (actual time=1249204.001..1249210.027 rows=1 loops=1)  
      ->  Gather  (cost=5554120.63..5554120.83 rows=2 width=8) (actual time=1249203.642..1249210.020 rows=3 loops=1)  
            Workers Planned: 2  
            Workers Launched: 2  
            ->  Partial Aggregate  (cost=5553120.63..5553120.63 rows=1 width=8) (actual time=1249153.615..1249153.616 rows=1 loops=3)  
                  ->  Parallel Seq Scan on doc_details  (cost=0.00..5456055.30 rows=38826130 width=0) (actual time=3.793..1245165.604 rows=31018949 loops=3)  
    Planning Time: 1.290 ms  
    Execution Time: …
    Run Code Online (Sandbox Code Playgroud)

postgresql count postgresql-12 query-performance

5
推荐指数
1
解决办法
5252
查看次数

Postgres 可以向后扫描索引吗?

我们使用 Amazon RDS 实例

x86_64-pc-linux-gnu 上的 PostgreSQL 11.13,由 gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-12) 编译,64 位

我有一个简单的经典每组前 1 名查询。我需要获取每个 的历史记录中的最新项目creativeScheduleId

这是表和索引的定义:

CREATE TABLE IF NOT EXISTS public.creative_schedule_status_histories (
  id serial PRIMARY KEY,
  "creativeScheduleId" text NOT NULL,
  -- other columns
);

CREATE UNIQUE INDEX IF NOT EXISTS idx_creativescheduleid_id
  ON public.creative_schedule_status_histories ("creativeScheduleId" ASC, id ASC);
Run Code Online (Sandbox Code Playgroud)

当引擎的查询排序时id ASC仅读取索引并且不执行任何额外的排序:

EXPLAIN (ANALYZE) 
SELECT history.id, history."creativeScheduleId"
FROM  (
    SELECT cssh.id, cssh."creativeScheduleId"
         , ROW_NUMBER() OVER (PARTITION BY cssh."creativeScheduleId"
                              ORDER BY cssh.id ASC) …
Run Code Online (Sandbox Code Playgroud)

postgresql index execution-plan window-functions greatest-n-per-group

5
推荐指数
1
解决办法
516
查看次数