标签: postgresql

为 WHERE COALESCE() 条件创建索引

我使用的是 PostgreSQL V9.6.11

表DDL:

CREATE TABLE test_c ( 
          insrt_prcs_id bigint NOT NULL, 
          updt_prcs_id bigint, src_sys_id integer NOT NULL,
          load_dttm timestamp(6) with time zone NOT NULL, 
          updt_dttm timestamp(6) without time zone);

Run Code Online (Sandbox Code Playgroud)

我试图index为下面的查询创建一个:

SELECT * 
FROM test_c             
WHERE COALESCE(u_dttm,l_dttm) > '2020-04-10 15:29:44.596311-07'
AND   COALESCE(u_dttm,l_dttm) <= '2020-04-11 15:29:44.596311-07' 
Run Code Online (Sandbox Code Playgroud)

创建index为:

create index idx_test_c  on test_c(COALESCE((updt_dttm, load_dttm)))
Run Code Online (Sandbox Code Playgroud)

但查询计划器没有扫描索引:

EXPLAIN ANALYZE
SELECT *            
FROM test_c             
WHERE COALESCE(u_dttm,l_dttm) > '2020-04-10 15:29:44.596311-07'
AND   COALESCE(u_dttm,l_dttm) <= '2020-04-11 15:29:44.596311-07' 
Run Code Online (Sandbox Code Playgroud)
Seq Scan on test_c as test_c (cost=0..1857.08 …
Run Code Online (Sandbox Code Playgroud)

postgresql index coalesce postgresql-9.6

4
推荐指数
1
解决办法
6460
查看次数

如何防止只读副本在高复制延迟期间重新启动

我们正在运行一个 Aurora PostgreSQL 集群,其中包含一个只读副本和主节点。

定期出现非常重的写入负载,导致较高的复制延迟。这可能会导致只读副本重新启动,这对于高可用性环境中的我们来说是不希望的。发生这种情况时,通过只读端点连接到集群的客户端会收到此 JDBC 错误:org.postgresql.util.PSQLException: FATAL: the database system is starting up。此外,AWS 控制台在日志中显示了这些内容:

只读副本已经落后于主数据库太多了。重新启动 postgres。

其次是

数据库实例已重新启动

我们可以容忍只读副本落后几分钟,但不能容忍只读副本重新启动才能赶上。

有没有办法防止只读副本在这些时间段内重新启动?

或者,是否有任何建议的调整可以减少写入负载较重期间的复制延迟?

postgresql replication aws-aurora

4
推荐指数
1
解决办法
4778
查看次数

如何在并发插入数据上使用 UUID v4 和创建时间进行分页?

语境:

出于好奇,我正在为我的应用程序进行负载测试。然后结果发生了很多并发插入。

在创建端点上进行负载测试后,我尝试在 Fetch 端点上进行负载测试,包括测试分页。对于分页,我组合了两列:id(带有 UUID v4 的 PK)和created_time。另外,我还添加了索引以加快排序速度。我从这里遵循这些解决方案。

问题:

由于数据是同时插入的,因此有几行具有相同的created_time,在我的例子中,同一时间戳最多有100(行)。

这是我的表架构,一个示例

BEGIN;

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

DROP TABLE IF EXISTS "payment_with_uuid";

CREATE TABLE "payment_with_uuid" (
 id VARCHAR(255) PRIMARY KEY NOT NULL DEFAULT (uuid_generate_v4()),
 amount integer NULL,
 name varchar(255) default NULL,
 created_time TIMESTAMPTZ NOT NULL DEFAULT (now() AT TIME ZONE 'utc')
);

CREATE INDEX idx_payment_pagination ON payment_with_uuid (created_time, id);

COMMIT;
Run Code Online (Sandbox Code Playgroud)

这是我的查询,

SELECT  * from payment_with_uuid ORDER BY  created_time DESC, id DESC LIMIT 10;
Run Code Online (Sandbox Code Playgroud)

它将返回 10 行付款,假设数据如下所示,并假设时间戳在第 …

postgresql pagination

4
推荐指数
1
解决办法
6234
查看次数

升级 Postgres 后查询性能下降

我在 PostgreSQL 12 数据库中有一个包含数百万条记录的表,从 11 升级到 12 后,一些查询开始表现得很糟糕。他们从大约 1 秒缩短到大约 5 分钟。我尝试重建所有索引、清理以及所有常见的 Postgres 容易实现的目标,但性能仍然很糟糕。

这是查询:

SELECT id, activity_count
FROM user
WHERE (search_index) @@ (to_tsquery('pg_catalog.english', '''1234567890'':*') AND active = true
ORDER BY activity_count DESC LIMIT 101
Run Code Online (Sandbox Code Playgroud)

换句话说,找到与给定帐号匹配的所有活跃用户,并从最活跃到最不活跃进行排序。

此查询大约需要 5 分钟才能返回 2 条记录。有什么不对劲。

该列search_index是一个 tsvector,存储表的各个文本字段中的所有关键字(只是帐户编号、名称等)。

我为此列创建了一个 GIN 索引:

CREATE INDEX user_search_index_gin
    ON public.user USING gin
    (search_index)
    TABLESPACE pg_default;
Run Code Online (Sandbox Code Playgroud)

我还有一个该active列的索引:

CREATE INDEX user_active
    ON public.user USING btree
    (active ASC NULLS LAST)
    TABLESPACE pg_default;
Run Code Online (Sandbox Code Playgroud)

我有一个有序索引activity_count

CREATE INDEX user_activity_count …
Run Code Online (Sandbox Code Playgroud)

postgresql statistics upgrade postgresql-12 query-performance

4
推荐指数
1
解决办法
4256
查看次数

在 postgres 中将 statements_timeout 显示为毫秒

我想创建一个视图,它将返回当前的数值(statement_timeout以毫秒为单位)。但是,该命令的结果SHOW是人类可读的,并且可能具有不同的后缀,例如minms

begin transaction;
set local statement_timeout = 120000; 
show  statement_timeout;
--------------
'2min'
Run Code Online (Sandbox Code Playgroud)

如何检索原始的、未翻译的值?

postgresql

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

为什么我的查询处于空闲状态?

我是 postgres 新手,我有 aws rds 实例运行 postgresql 引擎版本 11.5。

我所有的查询都是 clientRead 有 wait_event。为什么我的所有查询都处于空闲状态。这是否意味着它们在事务中处于空闲状态?

我应该采取哪些步骤来解决这个问题?

例如,如果我将idle_in_transaction_session_timeout更改为10分钟,它会解决这个问题吗?

select count(*),state FROM pg_stat_activity group by 2;
 count | state
-------+--------
     5 |
     1 | active
   451 | idle


Select pid, datname, usename, wait_event_type, wait_event, backend_type FROM pg_stat_activity where state='idle';
  pid  | datname  |         usename          | wait_event_type | wait_event |  backend_type
-------+----------+--------------------------+-----------------+------------+----------------
 14797 | xxxxx    | user                     | Client          | ClientRead | client backend


SELECT current_setting('idle_in_transaction_session_timeout');
 current_setting
-----------------
 1d
(1 row)
Run Code Online (Sandbox Code Playgroud)

postgresql amazon-rds postgresql-11 postgresql-performance

4
推荐指数
1
解决办法
5402
查看次数

当 UPDATE WHERE 子句进行表扫描时,Postgres 锁行为是什么?

假设您有一个包含数千万行的大表。

您想要UPDATE large_table SET col=value WHERE col=other_value...但未col建立索引,并且EXPLAIN显示该查询将对整个表执行 seq 扫描。

这里的锁行为是什么?根据大多数说法,Postgres 仅锁定 UPDATE 查询受影响的行,并且没有锁升级。那么它是否首先搜索要更新的行,然后只锁定找到的行?不过,在这种情况下,其他查询同时更新行似乎可能会出现问题。它是否“在找到每一行时”锁定它们,即在进行 seq 扫描时逐步锁定行?

因此,我认为这里最好的情况是它在找到行时锁定行,并且(仅)受影响的行将被锁定,直到 UPDATE 查询完成为止。

但我担心此查询可能最终会阻止对表的所有写入,直到完成为止。

我读过这篇文章: https: //habr.com/en/company/postgrespro/blog/503008/我认为最坏的情况不会发生,但在这里https://blog.heroku.com/curious-case-table -locking-update-query是类似信息的可能不准确表示,这让我有些怀疑。

该应用程序仅使用SELECT,SELECT FOR UPDATEUPDATE查询(即除这些之外没有其他显式锁)。该表有其他表的外键,其他表也有该表的外键。

我们使用的是 Postgres 11。

postgresql lock-escalation

4
推荐指数
1
解决办法
9477
查看次数

检查 Postgres 中查询的历史记录和日期

我正在PostgreSQL我的 Linux 终端上运行,如果我们选择pg_backend_pid();它,它会给出pid特定的会话。

下面只给出了最后执行的查询

select pid,
       usename as username,
       datname as database_name,
       query,
       application_name,
       backend_start,
       state,
       state_change
from pg_stat_activity
where pid = 'your-pid';
Run Code Online (Sandbox Code Playgroud)

但看起来这\s为我们提供了所有查询历史记录,但没有提供日期。我们可以和他们一起约会吗

如果我们确实将输出保存到文件名中,那么它会存储在Linux服务器上的哪里?

\s filename
Run Code Online (Sandbox Code Playgroud)

请建议是否有更具体的方法,实际上我正在寻找在特定日期执行的查询。

postgresql linux

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

更新期间意外违反唯一约束

foo在具有两列(id和)的表中seq,我想为seq具有任意 . 的所有记录添加+1 seq > 4738。计划是在seq=4739所有seq > 4738记录移动+1 后立即插入一条新记录。

这是桌子。

CREATE TABLE foo
(
  id uuid NOT NULL,
  seq integer NOT NULL,
  CONSTRAINT seq_key UNIQUE (seq)
)

CREATE UNIQUE INDEX idx_id
  ON foo
  USING btree
  (id);

CREATE UNIQUE INDEX idx_seq
  ON foo
  USING btree
  (seq);
Run Code Online (Sandbox Code Playgroud)

我尝试通过以下查询实现 +1 转变。请注意,我使用子查询尝试> 4738按降序更新记录(即假设 max seq=10000,则首先更新最后一条记录(10000->10001),然后更新倒数第二条记录(seq=10000此时不存在,seq=9999-> seq=10000(没有违反约束),然后是 9998 -> 9999,...以避免在任何时候发生唯一的约束违反。但是,这假设更新查询是顺序执行的,而这似乎并不是发生的情况。

跑步时

UPDATE foo SET seq=anon_1.new_seq FROM …
Run Code Online (Sandbox Code Playgroud)

postgresql subquery update unique-constraint

4
推荐指数
1
解决办法
4861
查看次数

在 PostgreSQL 外部数据包装服务器中创建共享用户映射

我们使用外部数据包装器在单个 PostgreSQL RDS 上跨数据库进行查询。外部数据包装服务器需要针对将查询远程服务器的每个用户的用户映射。然而,为每个用户添加用户映射可能很容易出错。

我们所有需要查询外部数据服务器的用户都有一个共享角色,例如role_name,在我们的 PostgreSQL 服务器上。

我们如何在用户之间共享外部数据包装服务器用户映射?

postgresql postgresql-fdw

4
推荐指数
1
解决办法
2205
查看次数