我在我的 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) 面临奇怪的行为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) 考虑以下示例:
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)
我很惊讶它仍然在测试中进行顺序扫描。简单地计算索引中的行数不是更快吗?
我正在尝试执行一项常见任务,从表中删除重复项,目的是添加唯一约束。
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 小时。对于我的示例方法来说,它可能仍在误差范围内,但我担心由于它不使用索引,这将花费指数时间。
这EXPLAIN有Seq Scan on item_identifier a和Seq 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) 我读过《深入了解 MySQL 和 PostgreSQL 中的隔离级别》和《读取现象》,尤其是“Postgres 中的序列化异常”部分。我想我已经理解了那里描述的问题,但是我很难判断它何时会在我的应用程序中发生。
是否只有使用 SUM/COUNT 这样的聚合函数才能在 Postgres 中获得序列化异常?如果不是,我还需要注意什么?
对于 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专栏?
我正在尝试解决一个特别困难的问题。我正在 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 …
我想将我的产品 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时出现同样的问题
我正在尝试优化包含超过 8000 万行的表。需要 20 多分钟才能获得行计数结果。我尝试过集群、vacuum full 和重新索引,但性能没有提高。为了改进数据查询和检索,我需要配置或调整什么?我在 Windows 2019 下使用 Postgresql 12。
更新信息:
Run Code Online (Sandbox Code Playgroud)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: …
我们使用 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
postgresql ×10
count ×2
exists ×2
index ×2
query ×2
aggregate ×1
amazon-rds ×1
concurrency ×1
distinct ×1
join ×1
pagination ×1
timescaledb ×1