标签: postgresql-11

SELECT 会像 V​​ACUUM 一样删除死行吗?

我在摆弄VACUUM并注意到一些意想不到的行为,其中SELECT从表中ing 行似乎减少了VACUUM之后必须做的工作。

测试数据

注意:autovacuum 被禁用

CREATE TABLE numbers (num bigint);
ALTER TABLE numbers SET (
  autovacuum_enabled = 'f',
  toast.autovacuum_enabled = 'f'
);

INSERT INTO numbers SELECT generate_series(1, 5000);
Run Code Online (Sandbox Code Playgroud)

试验 1

现在我们对所有行运行更新,

UPDATE numbers SET num = 0;
Run Code Online (Sandbox Code Playgroud)

当我们跑步时,VACUUM (VERBOSE) numbers;我们得到,

INFO:  vacuuming "public.numbers"
INFO:  "numbers": removed 5000 row versions in 23 pages
INFO:  "numbers": found 5000 removable, 5000 nonremovable row versions in 45 out of 45 pages
DETAIL:  0 dead row versions …
Run Code Online (Sandbox Code Playgroud)

postgresql select vacuum postgresql-11

9
推荐指数
1
解决办法
884
查看次数

如何设置每个用户的语句超时?

我在 Postgres 中有多个用户。我想为不同的用户设置不同的语句超时。
例如:访客 5 分钟,管理员 10 分钟。

在 Postgres 11.11 中可以吗?

postgresql configuration users query-timeout postgresql-11

8
推荐指数
1
解决办法
2万
查看次数

PostgreSQL 引用多个表最有效的方法

当一次只能进行一个引用时,我正在寻找在一个表中引用多个表的最有效方法。这意味着表 A 和 B 被表 C 引用,但 A 和 B 不能在 C 的一行中引用,并且我在编写查询时选择要查看的表。
我考虑过 4 种方法:

  • 有一个列type和一个列FK,这样我就可以进行像这样的连接type = 'A' AND a.pk = c.a_fk(这就是我们现在使用的)
  • 使用继承:A 和 B 都从“父”表继承序列,并且 C 具有“父”表的外键,但这在 PostgreSQL 中是不可能的
  • 使用与继承相同的原理,但使用另一个表 D。A 和 B 都有对 D 的引用,C 也有对 D 的引用,我可以像这样进行连接FROM c JOIN a ON a.d_fk = c.d_fk
  • 使用按表列我想要一个外键

在我尝试的每个解决方案中,查询规划器对于将返回多少行的判断都是错误的。
这是一个例子:我创建了一个简单的数据库,其中有 3 个表,如下所示:

                            Table "public.a"
 Column |  Type  | Collation | Nullable |            Default            
--------+--------+-----------+----------+-------------------------------
 pk     | bigint |           | not null | …
Run Code Online (Sandbox Code Playgroud)

postgresql performance database-design postgresql-9.6 postgresql-11 postgresql-performance

7
推荐指数
1
解决办法
1万
查看次数

字段名称中的 json_object_agg 错误为 null

PostgreSQL 版本:我的本地安装是 11.3,下面的小提琴是 10.0。两者的行为相同。

我有一个页面架构,每个页面都有部分,每个部分可以有不同类型的内容。当我查询某个页面时,我希望在 JSON 文档中输出有关该页面的所有信息。

我将 CTE 用于json_agg()每个部分的各种内容。最后,我将各个部分连接起来json_object_agg(),将部分标题映射到部分内容。

问题: json_object_agg()当页面没有任何部分时抛出错误。我已经通过使用没有章节标题的常规来验证有罪json_agg()。确切的错误:

error: field name must not be null
Run Code Online (Sandbox Code Playgroud)

我想要的:无论如何都不是错误。我不想在接收方进行自定义错误处理。如果查询可以返回 JSONNull来代替json_object_agg()没有部分的情况,那就更好了,但这是可选的。(欢迎其他优雅的解决方案)

文档

可能文档不完整或者我遗漏了一些东西。仅供参考。

聚合表达式上它说(强调我的):

大多数聚合函数都会忽略 null 输入,因此一个或多个表达式产生null 的行将被丢弃。除非另有说明,对于所有内置聚合,这可以 假定为 true 。

聚合函数中,json_object_agg()没有评论不处理null

将名称/值对聚合为 JSON 对象

摆弄错误的域参数。将域更改为其他选项可以使其正常工作。使用不存在的域也可以正常工作并返回 0 行。

询问

with secs as (
    select p.page_id, p.domain, s.section_id as sid, s.title as title
    from pages p
    left …
Run Code Online (Sandbox Code Playgroud)

postgresql aggregate json postgresql-10 postgresql-11

7
推荐指数
1
解决办法
1万
查看次数

如何在postgres中的记录之间交换主键

我似乎无法找到一种方法来实现这一点(或不)

我需要实现的是非标准的,因此我很难找到解决方案。

我需要编写一个数据迁移工具来将旧记录与表中的新记录“交换”,但我有以下要求/约束​​:

  • 不要丢失旧记录
  • 使对旧记录的所有引用都指向新记录(这不仅仅是 db 外键,它是我无法控制的外部服务、缓存、电子邮件、历史数据、书签等的引用)
  • 迁移代码需要与模式无关,即如果新列添加到表中并且独立于其他表引用它,则不需要更新。
  • 我无法锁定表超过更新两条记录所需的时间。

所以我的理想解决方案是,蛮力交换他们的主键......

问题是如何在 postgresql 中的两条记录之间交换主键。我很难找到一种不会因重复键异常而失败的方法,即一种以事务方式运行更新“验证”的方法。

我试过了

UPDATE table
SET id = (CASE id WHEN 1 THEN 2 WHEN 2 THEN 1 ELSE id END)
Run Code Online (Sandbox Code Playgroud)
UPDATE table
SET id = CASE id WHEN 1 THEN 2 WHEN 2 THEN 1 END
WHERE id IN (1, 2);
Run Code Online (Sandbox Code Playgroud)

都在重复键约束上失败

我正在使用 PostgreSQL 11.6


解决了

数字主键的批量更新解决方案,感谢以下好人的输入:

-- disable foreign key constraint validation
BEGIN;
SET session_replication_role='replica';

-- update the pairs of ids to their negative counterparts
WITH query …
Run Code Online (Sandbox Code Playgroud)

postgresql postgresql-11

7
推荐指数
3
解决办法
1549
查看次数

PostgreSQL 如何默认分区标识列?

PostgreSQL 11
为分区表上的标识列生成默认值的最佳方法是什么。
例如

CREATE TABLE data.log
(
  id              BIGINT GENERATED ALWAYS AS IDENTITY
                  (
                    INCREMENT BY 1
                    MINVALUE -9223372036854775808
                    MAXVALUE 9223372036854775807
                    START WITH -9223372036854775808
                    RESTART WITH -9223372036854775808
                    CYCLE
                  ),
  epoch_millis    BIGINT NOT NULL,
  message         TEXT NOT NULL

) PARTITION BY RANGE (epoch_millis);

CREATE TABLE data.foo_log
PARTITION OF data.log
(
  PRIMARY KEY (id)
)
FOR VALUES FROM (0) TO (9999999999);
Run Code Online (Sandbox Code Playgroud)

如果我做:

INSERT INTO data.foo_log (epoch_millis, message)
VALUES (1000000, 'hello');
Run Code Online (Sandbox Code Playgroud)

我得到:

错误:“id”列中的空值违反了非空约束
详细信息:失败的行包含(null,1000000,hello)。
SQL状态:23502

因为默认生成的值不会应用于分区,除非我将其插入到根表中,如下所示:

INSERT INTO data.log (epoch_millis, message)
VALUES …
Run Code Online (Sandbox Code Playgroud)

postgresql partitioning identity postgresql-11

6
推荐指数
1
解决办法
4722
查看次数

添加新列时使用不为空的默认值是否安全?

我们有一个由 Postgresql v11.4提供支持的 Rails 应用程序,我想在其中添加一个具有默认值和非空约束的新列,如下所示:

ALTER TABLE "blogs" ADD "published" boolean DEFAULT FALSE NOT NULL
Run Code Online (Sandbox Code Playgroud)

我知道添加具有默认值的新列是安全的。但是,与 组合使用仍然安全吗NOT NULL?或者它会锁定数据库吗?谢谢!

postgresql null default-value alter-table postgresql-11

6
推荐指数
1
解决办法
1万
查看次数

BRIN 索引是否支持 ENUM 类型?

BRIN 索引似乎很有用,但我不确定如何在 ENUM 类型上使用。我认为这段代码会起作用:

CREATE TYPE test_enum AS ENUM ('a', 'b');
CREATE TEMPORARY TABLE my_table (
    x test_enum
);

CREATE INDEX test_index ON my_table using brin (x);
ERROR:  data type test_enum has no default operator class for access method "brin"
Run Code Online (Sandbox Code Playgroud)

我是否必须从头开始创建一个新的运算符类?枚举不是已经订购了吗?

这个提交,从 2014 开始,意味着 BRIN 索引应该适用于 ENUM 类型。

postgresql index enum postgresql-10 postgresql-11

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

在 Postgres 中提取全表的最快方法

我正在尝试将一个包含 50M 记录的表转储到一个文件中,我的目标是减少执行此操作的时间。我通常使用COPY metrics TO 'metrics.csv' DELIMITER ',' CSV;在最好的情况下这可能需要一个小时。我也有兴趣以某种普通格式导出数据(避免使用pd_dump目录)。

其中一个想法是通过条件或游标以某种方式访问​​此表,该条件或游标将整个表拆分为相同大小的部分,因此您可以同时执行例如 2 个复制查询,从而将时间减少一半。

例子:

COPY (SELECT * FROM metrics WHERE id < 25000000) TO 'metrics_1.csv' DELIMITER ',' CSV;
COPY (SELECT * FROM metrics WHERE id >= 25000000) TO 'metrics_2.csv' DELIMITER ',' CSV;
Run Code Online (Sandbox Code Playgroud)

在这些条件下创建的部分索引有帮助吗?

有什么想法是实现表的这种部分复制转储的好方法吗?有没有其他解决方案可以更快地转储此表?

Postgresql 11 / 100GB RAM / 20 核。

在与COPYIO 边界进行一些并行化之后,这似乎不是瓶颈。

在此处输入图片说明

postgresql dump copy postgresql-11

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

从 Postgres 11 中的服务器端过程返回多个结果集

Postgres 咨询公司的这篇博文提到 Postgres 11 中新的服务器端过程支持将能够返回多个结果集。

? 这个特性确实出现在 Postgres 11 版本中吗?

如果是这样,你能简单解释一下它是如何工作的吗?显示一些代码示例?

postgresql stored-procedures postgresql-11

5
推荐指数
2
解决办法
4175
查看次数