标签: postgresql

Postgresql将多行查询结果赋值给变量并继续执行

我正在尝试创建一个脚本来调用 PostgreSQL 中的多个存储过程并打印其中一些的结果:

CREATE OR REPLACE FUNCTION script(
vtoken character varying) 
  RETURNS void AS
$BODY$
DECLARE
  aux character varying;
BEGIN

PERFORM (SELECT acquire_table(vtoken));

-- This query gets the dynamically generated token for the client in that codebar
aux := (SELECT token 
                FROM clients c JOIN tables t ON c.tablekey = t.tablekey 
                WHERE codebar = vtoken);

PERFORM (SELECT order_drinks(aux, '{1}', '{1}'));

--EXECUTE (SELECT issue_ticket(aux));

PERFORM (SELECT order_drinks(aux, '{1}', '{1}'));


END;$BODY$
  LANGUAGE plpgsql VOLATILE
Run Code Online (Sandbox Code Playgroud)

issues_ticket() 函数返回多行结果,我想直接打印它并继续执行下一个函数(order_drinks())。如果我执行 PERFORM,它不会显示结果,如果我只是尝试按原样执行 SELECT 查询,它会要求将返回值分配给变量。

postgresql

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

Postgres 中匹配条件的行数上限

假设我有一个像这样的数据库模式

user_id text
photo_id text
date_created timestamp
Run Code Online (Sandbox Code Playgroud)

我想强制执行“一个用户只能拥有 30 张照片”的约束。实现这一点的一个天真的方法是

SELECT COUNT(*) FROM user_photos WHERE user_id='usr_123'
Run Code Online (Sandbox Code Playgroud)

将结果与 30 进行比较,如果较低,则进行插入。天真,因为如果您可以在短时间内触发多个请求,您就可以赢得一场比赛并最终写入 30 多个记录。

有没有办法在数据库中强制执行此约束?例如创建某种索引“只能插入 30 行”,或者什么?有没有办法让一个count列为每个 userId 单独递增,并且可以将其范围限制为0-29

如果您使用事务,会锁定您读取的行吗?

postgresql index constraint

7
推荐指数
2
解决办法
6005
查看次数

如何估计重建索引时间?

如何估计在 PostgreSQL 中重新索引整个表所需的总时间?

我有一个大型 PostgreSQL 数据库,其主表有 1500 万行、100 列和 200 个索引。

我发现一个问题,经过一整夜的进程将数据加载到表中后,在加载结束后大约 3-6 小时内,对表的查询非常慢。然而,这些查询在加载后 6 小时后奇迹般地再次变快。

这种暂时的缓慢是否是由 Postgres 在后台更新索引引起的?如何加快此处理速度?我找不到任何控制这个的参数。

我正在考虑REINDEX加载结束后立即在桌子上运行 a ,但我不确定这需要多长时间,而且我担心它可能需要比原始加载更长的时间,并且只会恶化性能。

我的表存储了有关客户的数十个描述符,索引(其中许多是部分索引)用于加速用户运行的常规查询。

该数据库接近 1 TB,因此我很少将整个数据库加载到开发环境中。相反,我有一个复制几千条记录的脚本。

postgresql index

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

从列中获取 ts_query 语言时,不使用 PostgreSQL GIN 索引

我有一个存储一些多语言内容的表:

CREATE TABLE search (
  content text NOT NULL,
  language regconfig NOT NULL,
  fulltext tsvector
);

CREATE INDEX search_fulltext ON search USING GIN(fulltext);

INSERT INTO search (language, content) VALUES 
  ('dutch', 'Als achter vliegen vliegen vliegen vliegen vliegen vliegen achterna'),
  ('dutch', 'Langs de koele kali liep een kale koeli met een kilo kali op zijn kale koeli-kop.'),
  ('dutch', 'Moeder sneed zeven scheve sneden brood'),
  ('english', 'I saw Susie sitting in a shoe shine shop. Where she sits she shines, and where …
Run Code Online (Sandbox Code Playgroud)

postgresql full-text-search gin-index

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

在 PostgreSQL URL 中,我不能使用包含特殊字符的密码

我在 Azure 中有一个 postgresql 数据库

passwd中的字符串中包含特殊字符这样的:

)mvd99/iyH_=ag=Por/W}%%aKY^ygt+,sC7%%P?APOU
Run Code Online (Sandbox Code Playgroud)
psql --dbname=postgresql://db_user@mydemoserver:)mvd99/iyH_=ag=Por/W}%%aKY^ygt+,sC7%%P?APOU@mydemoserver.postgres.database.azure.com:5432/mydb
Run Code Online (Sandbox Code Playgroud)

执行 psql 命令时,它显示以下错误:

psql: invalid percent-encoded token: "iyH_=ag=Por/W}%%aKY^ygt+,sC7%%P"
Run Code Online (Sandbox Code Playgroud)

我已经尝试将 passwd 字符串放在引号中,但它不起作用

我还有什么其他选择?我无法更改密码

我对使用 psql 客户端很感兴趣,因为我必须做非常大的备份

postgresql psql password

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

期望 Postgresql WAL 的大小缩小,但事实并非如此

我们max_wal_size最近将其设置为 24 GB(默认为 1 GB),进行了一些测试,然后将其设置为 12 GB,然后重新启动服务器。当我在文件系统上查询 WAL 的大小(pg_xlog目录中文件的总大小)时,它仍然显示为大约 20 GB。我已经发布了一个手动检查点并重新启动了服务器,但 WAL 并没有缩小到 12 GB。这是一个非常简单的实现——没有复制或存档,也不存在长时间运行的事务。我误解了这应该如何工作吗?当您降低max_wal_size值并完成所有事务并且服务器重新启动时,它是否不会删除旧的 WAL 文件?

Postgres 版本:9.6.15

操作系统:Linux Ubuntu 16.04.6 LTS

设置:

max_wal_size = 12GB

min_wal_size = 80MB

wal_keep_segments = 0

checkpoint_timeout = 15 分钟

checkpoint_completion_target = 0.87

wal_compression = 关闭

存档模式 = 关闭

wal_level = 最小

postgresql write-ahead-logging

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

如何更改 Postgres 12 GENERATED 列的定义

如何更改 Postgres 12 GENERATED 列的定义?

CREATE TABLE test (
    id serial PRIMARY KEY,
    val_a int4 NOT NULL DEFAULT 0,
    val_b int4 NOT NULL DEFAULT 0,
    val_sum int4 generated always AS (val_a + val_b) stored
);
Run Code Online (Sandbox Code Playgroud)

我试过

ALTER TABLE test ALTER COLUMN val_sum TYPE int4 generated always AS (val_a + val_b + 1) stored;
ALTER TABLE test ALTER COLUMN val_sum SET generated always AS (val_a + val_b + 1) stored;
Run Code Online (Sandbox Code Playgroud)

但两者都会出现语法错误。

另一种方法是删除并添加列,这是可行的,但我想知道如何像任何其他列一样简单地更改它。

postgresql computed-column

7
推荐指数
2
解决办法
3748
查看次数

如何在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
查看次数

psql \e 的鲁莽行为

psql 13.2 退出编辑器时,无论退出编辑器后如何,都会执行查询缓冲区 - 在这种情况下,缓冲区现在可能保存最近执行的 SQL 查询。

重现:

  1. vim使用\e\e filenamepsql控制台启动编辑器(在我的情况下)。
  2. 输入与否,没有区别。
  3. 取消编辑:q(或:q!强制)

预期行为:回到启动编辑器之前的状态。(我取消了编辑!)
观察到的行为:重新执行上次执行的 SQL 查询。

似乎发生了什么\e

  1. 它执行(相当于)\p,因此当前查询缓冲区包含前一个命令,当它为空时。(编辑文件时用户看不到!) 手册\p

    \p 或者 \print

    将当前查询缓冲区打印到标准输出。如果当前查询缓冲区为空,则打印最近执行的查询。

  2. 启动编辑器。如果提供了文件名,则加载文件,否则加载查询缓冲区。

  3. 如果编辑器以写入结束,则将结果复制到查询缓冲区。
    如果编辑被取消(:q在 vim 中),不要覆盖查询缓冲区。(它现在保存了之前的命令!)

  4. 执行查询缓冲区。或者,准确地说,这样做:

行为似乎可以\p(只是复制查询缓冲区,没有造成任何伤害),但不能\e执行,它可以执行我什至没有看到的命令。

这是一个错误吗?
无论哪种方式,我至少想在离开编辑器时禁用自动执行。但这似乎不可能。或者我错过了什么?

postgresql psql

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

我是否正确理解索引?

我正在努力解决各种数据库索引之间的差异。我为自己创建了一个小例子,我不知道我是否正确理解了所有内容。

假设我们有一个这样的虚构数据库表:

addr col1  col2
===============
1    a     b
2    c     b
3    a     c
4    d     d
5    c     a
6    a     b
7    c     b
8    d     d
9    a     c
Run Code Online (Sandbox Code Playgroud)

addr这是相应元组的物理位置。这是我对单列、多列和覆盖索引的外观的理解(不是物理上的,而是概念上的):

create index on col1
a - 1, 3, 6, 9
c - 2, 5, 7
d - 4, 8

create index on (col1, col2)
a b - 1, 6
a c - 3, 9
c a - 5
c b - 2, 7
d d …
Run Code Online (Sandbox Code Playgroud)

postgresql index performance-tuning

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