标签: postgresql

获取包含每列最后一个非 NULL 值集的行

假设有一张表

version col_A   col_B   col_C
1       A1      B1     (null)
2       A2      B3     (null)
3       A3      B2     (null)
4       A5     (null)   C1
5       A1     (null)  (null)
Run Code Online (Sandbox Code Playgroud)

我需要的是获取 Postgres 中每列的最后一个非空值,即对于上表,我期望结果为(A1,B2,C1)。

这里的“last”是指当表按列版本排序时,每列中的最后一个非空值。

版本列始终仅包含非空值。

该表不会很大,因为只有几千行。所以,不太担心性能。

postgresql

6
推荐指数
3
解决办法
4676
查看次数

如何检查 int[] 数组是否包含小于 X 的值?

我们可以使用 来检查数组中是否包含特定值'X' = ANY(haystack)。但是,如何检查整数数组是否包含小于 X 的值?例如,我想查找至少有一个值小于 100 的所有数组。

postgresql

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

MS SQL Server 支持“功能索引”吗?

我在阅读 PostgreSQL 文档时刚刚遇到基于表达式的索引(又名“功能索引”)(我以前不知道此类索引)。

我只是想知道 Microsoft SQL Server 中是否有与此类似/等效的内容?我已阅读有关索引的 SQL Server 文档,但没有看到任何明显相似/等效的内容。

postgresql index sql-server functions

6
推荐指数
3
解决办法
2607
查看次数

UPDATE 是否会为未更改的 TOAST 值写入新的行版本?

我正在使用一个带有大型 TEXT 字段的 PostgreSQL 表,理论上该表会定期更新。我曾考虑过将数据直接存储在文件系统中,但使用 TOAST 时,数据已经存储在页外并压缩在数据库中,所以我想我会让事情变得简单,只使用数据库存储。

为了提供一些背景信息,我正在为 RSS 提要建立索引。我将每 24 小时运行一个脚本来提取 RSS 源并可能更新表格。这可能会导致大量死元组,从而占用大量磁盘空间。当然,autovacuum 最终会处理这个问题,但它可能会产生大量数据(很多 GB),我想确保我知道当我在这个非常大的表上进行大量更新时会发生什么。

我的一个解决方案是仅在提要发生某些重大更改(例如网站上出现新帖子)时才更新 TEXT 字段(存储 RSS 数据)。这意味着我可以避免进行更新,除非确实必须这样做。但是,我仍然想更新该表(以跟踪我最近执行 HTTP 请求的时间)。这将使用旧版本的行数据创建一个死元组。

如果 TEXT 数据实际上没有改变,会发生什么情况?当 UPDATE 创建死元组时,它还会复制 TEXT 数据吗?或者 TEXT 数据会保持不变,因为它没有更改并且存储在页外?

postgresql disk-space vacuum update autovacuum

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

WHERE 子句中未使用的列

我在我们的代码库中找到了这个查询:

DELETE FROM "Foo"
WHERE ("Foo"."Id", "Foo"."CreatedAt")
IN (SELECT "f"."Id", "f"."CreatedAt"
    FROM "Foo" AS "f"
    WHERE "f"."CreatedAt" <= CURRENT_TIMESTAMP);
Run Code Online (Sandbox Code Playgroud)

它删除当前时间之前创建的记录。

这给出了相同的结果:

DELETE FROM "Foo"
WHERE "Foo"."CreatedAt"
IN (SELECT "f"."CreatedAt"
    FROM "Foo" AS "f"
    WHERE "f"."CreatedAt" <= CURRENT_TIMESTAMP);
Run Code Online (Sandbox Code Playgroud)

我不知道为什么Foo.Id将 包含在WHERE子句中 - 也许是各种重构留下的垃圾(例如,它可能已用于批量删除ORDER BY "f"."Id" LIMIT 1000)。但因为这是一场PK,我不愿意删除它,因为也许它的存在是有原因的。

是否有理论/性能原因将其放在那里,或者这两个查询是否等效?

(这同时针对 postgres 和 sqlite。)

postgresql sqlite query subquery relational-theory

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

可以使用 CASE 选择要 JOIN 的表吗?

我正在尝试使用 CASE 表达式来选择每行应与哪个表连接。

假设我的游戏中有一个 item_instances 表,其中包含游戏世界中的所有项目,其中一些项目是 item_templates 表中通用项目的千篇一律的副本,而其他项目则以模板开始,然后当玩家使用它们时获得独特的属性。它们现在存储在 unique_items 表中。

因此,当我在 item_instances 表中找到某个项目的记录时,我想查找有关它的更多信息,并且需要从正确的表中提取该信息。

这是我一直在尝试但没有成功的事情:

SELECT item_table, item_id, *
FROM item_instances AS ii
JOIN
CASE ii.item_table
    WHEN 0 THEN 'item_templates'
    WHEN 1 THEN 'unique_items'
    ELSE 'unique_items'
END
ON CASE = ii.item_id;
Run Code Online (Sandbox Code Playgroud)

如果有语法的快速修复,我很想听听。或者,如果这是您在概念上无法做到的事情 - 让每一行选择自己的连接 - 我很乐意获得更深入解释的链接。

过去,我通过执行两个 SELECT 来完成类似的操作,其中一个针对 item_templates 表,另一个针对 unique_items 表,并采用它们的 UNION。这感觉是一种更正确且更少浪费的方法。如果不是出于某种原因与 SQL 更深层次的架构有关,我想了解为什么。

postgresql join case

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

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

我们有一个由 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万
查看次数

使用 INCLUDE 相对于在 INDEX 中添加列来覆盖索引的优势

Postgres 文档声明了以下有关仅索引扫描和覆盖索引的内容

如果您经常运行类似的查询

SELECT y FROM tab WHERE x = 'key';

加速此类查询的传统方法是仅在 x 上创建索引。然而,索引定义为

CREATE INDEX tab_x_y ON tab(x) INCLUDE (y);

可以将这些查询作为仅索引扫描来处理,因为可以从索引中获取 y 而无需访问堆。

因为列 y 不是索引搜索键的一部分,所以它不必是索引可以处理的数据类型;它仅存储在索引中,并且不被索引机制解释。另外,如果索引是唯一索引,即

CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y);

唯一性条件仅适用于 x 列,不适用于 x 和 y 的组合。(INCLUDE 子句也可以用 UNIQUE 和 PRIMARY KEY 约束编写,为设置这样的索引提供替代语法。)

问题1:如果 的数据类型y可以添加到索引中,并且没有唯一性要求,那么使用CREATE INDEX tab_x_y ON tab(x) INCLUDE (y)overCREATE INDEX tab_x_y ON tab(x, y)进行查询有什么优势SELECT y FROM tab WHERE x = 'key';

在向索引添加非键有效负载列(尤其是宽列)时保持保守是明智的做法。如果索引元组超过索引类型允许的最大大小,数据插入将失败。在任何情况下,非键列都会复制索引表中的数据并使索引的大小膨胀,从而可能会减慢搜索速度。 …

postgresql index covering-index

6
推荐指数
2
解决办法
4398
查看次数

pgAdmin 是否增加了查询时间开销?

我刚刚写了一个很长的问题,关于我如何优化一个相当简单的查询,该查询花费的时间比我希望的要长得多。我一直向pgAdmin查询。然后我使查询变得越来越简单,直到我最终查询一个新创建的表的主键,其中只有 1 行。

create table perf_test (id bigint primary key);
Run Code Online (Sandbox Code Playgroud)

然后查询:

select
  count(t.id)
from
  perf_test t
where
  t.id = 1
;
Run Code Online (Sandbox Code Playgroud)

消息输出为:

Successfully run. Total query runtime: 66 msec.
1 rows affected.
Run Code Online (Sandbox Code Playgroud)

我需要优化一个查询,该查询从我的应用程序发出时通常需要大约 30-40 毫秒。如果 pgAdmin 中最简单的查询的执行时间已经长得多,我该如何实验和测量性能?

postgresql pgadmin query-performance

6
推荐指数
2
解决办法
2004
查看次数

设置二级 citus 工作人员的正确方法

我正在尝试 postgres-addon citus。到目前为止,我已经设置了一个包含一个协调器和三个工作节点的集群。

现在我想为其中一个工作节点设置辅助节点。到目前为止,我已经设置了从该工作节点到第四个(备用)节点的流复制。

我现在是否必须使用add_node和 noderole“辅助”将备用节点添加为辅助节点?

citus_add_secondary_node更好,因为您必须使用该命令定义合适的主节点?

或者,设置一个带有 citus 扩展的新数据库就足够了,并且add_node/ secondary会将该节点转变为包含来自工作线程的所有数据的辅助节点?

我使用以下命令获得了辅助节点的正确组 ID:

select * from pg_dist_node;
Run Code Online (Sandbox Code Playgroud)

postgresql standby citus

6
推荐指数
0
解决办法
241
查看次数