我正在对我公司的一些 SQL 进行一些性能基准测试,将 PG10 与 PG12 进行比较。我们在代码中使用了很多CTE,而 PG12 并没有对 CTE 进行原生优化,因此 PG10 和 PG12 之间的性能是相同的。
我的下一个实验是将NOT MATERIALIZED指令添加到 CTE,结果令人震惊:它大大缩短了查询时间(在某些情况下将它们减半)。
我在这里读到这MATERIALIZED是 PG12 之前的默认功能。该功能会将 CTE 的所有内容写入一个临时位置。
所以我的问题主要是NOT MATERIALIZED:
NOT MATERIALIZED功能对幕后的数据MATERIALIZED有何作用? NOT MATERIALIZED在重构我们的代码库之前,我应该注意哪些副作用?我有两个进程并行执行这样的代码:
begin;
update foos set unread=false where owner_id=123 and unread=true;
commit;
Run Code Online (Sandbox Code Playgroud)
这会导致死锁。
我对导致死锁的原因的理解就像这个问题中描述的场景,“交织” UPDATE 语句以不同的顺序更新两个不同的行。我不明白单个 UPDATE 语句如何导致死锁。我无法在我的开发环境中使用两个并行 psql 会话来复制死锁场景。我为什么不能复制它的猜测:
这个单一的 UPDATE 是否有可能造成死锁?
我以前总是这样做:
SELECT column FROM table ORDER BY random() LIMIT 1;
Run Code Online (Sandbox Code Playgroud)
对于大表,这令人难以忍受,慢得令人难以置信,以至于在实践中毫无用处。这就是为什么我开始寻找更有效的方法。人们推荐:
SELECT column FROM table TABLESAMPLE BERNOULLI(1) LIMIT 1;
Run Code Online (Sandbox Code Playgroud)
虽然速度很快,但它也提供了毫无价值的随机性。它似乎总是选择相同的该死的记录,所以这也毫无价值。
我也试过:
SELECT column FROM table TABLESAMPLE BERNOULLI(100) LIMIT 1;
Run Code Online (Sandbox Code Playgroud)
它提供了更糟糕的随机性。它每次都选择相同的几条记录。这是完全没有价值的。我需要实际的随机性。
为什么仅选择随机记录显然如此困难?为什么它必须抓取每条记录然后对它们进行排序(在第一种情况下)?为什么“TABLESAMPLE”版本总是抓取相同的愚蠢记录?为什么它们不是随机的?当它一遍又一遍地选择相同的几条记录时,谁会想要使用这个“BERNOULLI”的东西?我不敢相信,经过这么多年,我仍然在询问随机记录……这是最基本的查询之一。
用于从 PG 中的表中抓取随机记录的实际命令是什么,该命令并没有慢到需要几秒钟才能获得一个体面大小的表?
将应用程序及其数据库从经典 PostgreSQL 数据库迁移到 Amazon Aurora RDS PostgreSQL 数据库(均使用 9.6 版本)后,我们发现特定查询在 Aurora 上的运行速度要慢得多——大约慢 10 倍在 PostgreSQL 上。
两个数据库都具有相同的配置,无论是硬件还是 pg_conf。
查询本身相当简单。它是从我们用 Java 编写的后端生成的,并使用 jOOQ 编写查询:
with "all_acp_ids"("acp_id") as (
select acp_id from temp_table_de3398bacb6c4e8ca8b37be227eac089
)
select distinct "public"."f1_folio_milestones"."acp_id",
coalesce("public"."sa_milestone_overrides"."team",
"public"."f1_folio_milestones"."team_responsible")
from "public"."f1_folio_milestones"
left outer join
"public"."sa_milestone_overrides" on (
"public"."f1_folio_milestones"."milestone" = "public"."sa_milestone_overrides"."milestone"
and "public"."f1_folio_milestones"."view" = "public"."sa_milestone_overrides"."view"
and "public"."f1_folio_milestones"."acp_id" = "public"."sa_milestone_overrides"."acp_id"
)
where "public"."f1_folio_milestones"."acp_id" in (
select "all_acp_ids"."acp_id" from "all_acp_ids"
)
Run Code Online (Sandbox Code Playgroud)
用temp_table_de3398bacb6c4e8ca8b37be227eac089是单个列的表,f1_folio_milestones(17万个条目)和sa_milestone_overrides(100万左右的条目)是具有在所有用于列索引类似设计的表LEFT OUTER JOIN。
temp_table_de3398bacb6c4e8ca8b37be227eac089 最多可以包含 5000 …
postgresql optimization execution-plan aws-aurora postgresql-performance
我在 pg_toast 中有相当多的存储空间
relation | size
----------------------------------+---------
pg_toast.pg_toast_43934449 | 87 GB
pg_toast.pg_toast_43934438 | 64 GB
pg_toast.pg_toast_50877 | 35 GB
pg_toast.pg_toast_16715 | 15 GB
pg_toast.pg_toast_16813 | 13 GB
pg_toast.pg_toast_5706469 | 1335 MB
pg_toast.pg_toast_43934449_index | 1004 MB
pg_toast.pg_toast_43934438_index | 942 MB
pg_toast.pg_toast_16715_index | 709 MB
pg_toast.pg_toast_16813_index | 548 MB
pg_toast.pg_toast_50877_index | 530 MB
pg_toast.pg_toast_3518414 | 463 MB
pg_toast.pg_toast_16994 | 339 MB
pg_toast.pg_toast_46608 | 310 MB
pg_toast.pg_toast_16994_index | 92 MB
pg_toast.pg_toast_22345124 | 68 MB
pg_toast.pg_toast_46608_index | 51 MB
pg_toast.pg_toast_437018 | 43 MB
pg_toast.pg_toast_5706469_index …Run Code Online (Sandbox Code Playgroud) 我有一个 Postgresql 11 数据库。假设我有一张桌子,叫做houses。它应该有数十万条记录。
CREATE TABLE houses (
pkid serial primary key,
address varchar(255) NOT NULL,
rent float NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
现在,我的房子有我想在数据库中注册的功能。由于可能的功能列表会很长(几十个)并且会随着时间的推移而演变,因为我不想在表屋中添加一长串列并使用“ALTER TABLE”不断更改表,我想到了这些功能有一个单独的表格:
CREATE TABLE house_features (
pkid serial primary key,
house_pkid integer NOT NULL,
feature_name varchar(255) NOT NULL,
feature_value varchar(255)
);
CREATE INDEX ON house_features (feature_name, feature_value);
ALTER TABLE house_features ADD CONSTRAINT features_fk FOREIGN KEY (house_pkid) REFERENCES houses (pkid) ON DELETE CASCADE;
Run Code Online (Sandbox Code Playgroud)
平均而言,每个房屋记录在house_features表中将有 10-20 条记录。
到目前为止,这似乎是一个简单高效的模型:我可以添加尽可能多的不同功能,控制上层(应用层和/或 GUI)中feature_name和feature_value的可能值。每次应用程序发展时我都不必更改数据库,我需要一种新的功能。 …
目前我正在使用一个看起来像这样的 postgres 表 (postgres12)
create table if not exists asset (
id text,
symbol text not null,
name text not null
primary key (id)
);
create table if not exists latest_value (
timestamp bigint,
asset text,
price decimal null,
market_cap decimal null,
primary key (asset),
foreign key (asset)
references asset (id)
on delete cascade
);
create table if not exists value_aggregation (
context aggregation_context,
timestamp bigint,
asset text,
price jsonb null,
market_cap jsonb null,
primary key (context, timestamp, asset),
foreign …Run Code Online (Sandbox Code Playgroud) 在开发和测试期间,VALUES 文字表达式非常有用,因为它们使您能够在 SQL 查询中存储数据定义。
WITH foobar(foo, bar) AS (
VALUES
(1::integer,'a'::text),
(2,'b'),
(3,'c'),
(4,'d')
)
SELECT * FROM foobar;
Run Code Online (Sandbox Code Playgroud)
然而,当尝试使用非常宽或大的表时,这可能会变得乏味。如果这可以从现有表中生成,那就更令人沮丧了。
所以我有一种方法可以轻松地将行作为文字 VALUES 表达式复制/粘贴吗?
我能得到的最接近的是输出行作为记录
(请注意元数据,因为此 SQL 实际上尝试从给定的文字 VALUES 反向工程文字 VALUES)。
WITH foobar(foo, bar) AS (
VALUES
(1::integer,'a'::text),
(2,'b'),
(3,'c'),
(4,'d')
)
SELECT foobar::record FROM foobar;
Run Code Online (Sandbox Code Playgroud)
这是 psql 输出:
foobar
--------
(1,a)
(2,b)
(3,c)
(4,d)
(4 rows)
Run Code Online (Sandbox Code Playgroud)
然而,这需要额外的编辑来正确引用、键入和转义内容,所以我应该寻找格式化输出技巧还是 SQL 技巧?
编辑:当前的最佳答案已经非常好,但理想情况下,我想知道是否有通用方法来生成可以适应您可以抛出的任何记录类型的值表达式(即使它是带有随机数的复合行列)。
假设可以将其包装为如下函数:
row_to_values(IN myrowtype record, OUT myrowtype_as_literal_values text)
Run Code Online (Sandbox Code Playgroud)
在这个阶段,人们可能想知道“为什么不使用 row_to_json() ?” 是的,这可能是一个有效的替代方案,但我们正在偏离我想到的初始用例(快速生成用于测试/偶尔目的的 SQL),尽管使用 json 应该表现良好并且现在在 PostgreSQL 版本中广泛可用。
更好的是一个聚合函数,它直接输出一个干净的文本定义,在第一个 VALUE 上指定类型并添加列名作为别名(但在这个阶段,它几乎是一个功能提案,这里不是正确的地方,我没有人问对于这样的事情)。 …
我编写了一个简单的查询,它应该以人类可读的格式显示任何给定模式的所有表大小:
select table_name, pg_relation_size(quote_ident(table_name))
from information_schema.tables
where table_schema = 'my_schema'
order by 2
Run Code Online (Sandbox Code Playgroud)
当我在 PgAdmin 中运行此查询时,出现以下错误:
ERROR: relation "my_table" does not exist
SQL state: 42P01
Run Code Online (Sandbox Code Playgroud)
这个错误怎么可能?我根本没有改变 information_schema ,如果关系首先不存在,为什么它会在 information_schema 中?知道这是怎么发生的吗?
我有一张像下面这样的表格,我想按日期订购这张表格而不打破组。
id group date
1 | group1 | 2011-11-24
2 | group2 | 2011-08-20
3 | group1 | 2011-03-11
4 | group3 | 2011-05-05
5 | group3 | 2012-01-01
Run Code Online (Sandbox Code Playgroud)
按日期排序时,我只考虑最新更新的组元素。
我想得到这样的订单;
id group date
5 | group3 | 2012-01-01
4 | group3 | 2011-05-05
1 | group1 | 2011-11-24
3 | group1 | 2011-03-11
2 | group2 | 2011-08-20
Run Code Online (Sandbox Code Playgroud) postgresql ×10
optimization ×3
aws-aurora ×1
concurrency ×1
deadlock ×1
psql ×1
random ×1
schema ×1
select ×1
transaction ×1
update ×1