在 PostgreSQL 中将枚举值转换为字符串的正常方法是对其进行强制转换(使用::text),或者在将其连接到另一个字符串时简单地依赖隐式转换:
testdb=# CREATE TYPE color AS ENUM ('red', 'green', 'blue');
CREATE TYPE
testdb=# CREATE TABLE object (id serial, name text, color color);
CREATE TABLE
testdb=# INSERT INTO object (name, color) VALUES ('table', 'red'), ('chair', 'green');
INSERT 0 2
testdb=# SELECT name || color FROM object;
?column?
------------
tablered
chairgreen
(2 rows)
Run Code Online (Sandbox Code Playgroud)
然而,有一个问题:Postgres似乎并不认为这种转换是不可变的。因此,如果您尝试在需要不可变表达式的地方(例如在列的定义中)使用它们,您会收到GENERATED错误:
testdb=# ALTER TABLE object ADD COLUMN namecolor text GENERATED ALWAYS AS (name || color) STORED;
ERROR: generation expression is …Run Code Online (Sandbox Code Playgroud) 对于以下表来说,什么是好的自动真空设置(建议):
高写表插入负载
一天内插入 30-10,000 次。该表可以在没有负载的情况下闲置数周,但每周至少可以进行 3 次突发插入。
高更新表
它使用分区表数据,单次插入的大小是我的表大小的 3-8 倍。
高写表
单行仅更新一次,但一天内会突然更新唯一键,并且需要更新,可能是 30-10,000 个键更新。
高读表
大多数表都是高读取表,为我的数据仓库设置填充因子 80,容纳来自高更新表计算的表
我的删除每月进行一次并分批进行。与密钥相关的所有内容都会被删除或作为备份移动。
目前,对于高更新表,我的填充因子设置为 10-20 。
使用 TDS db.t3.large,但我在流量较低时切换到 db.t3.micro。
另外,设置填充因子真的很低会减慢选择速度吗?
阅读有关数字数据类型的Postgresql 文档
让我想到了这个问题:为什么在 Postgresql 中使用数据类型Float(SQL 标准)会得到这些意外的结果Numeric?
例如:
CREATE TEMP TABLE testnum (a numeric, b float);
INSERT INTO testnum VALUES (100,100);
INSERT INTO testnum VALUES (9*9*9,9*9*9);
INSERT INTO testnum VALUES (9^9^9,9^9^9);
SELECT (a/3)*3 AS numeric, (b/3) * 3 AS float FROM testnum;
SELECT (a/5)*5 AS numeric, (b/5) * 5 AS float FROM testnum;
Run Code Online (Sandbox Code Playgroud)
然后运行
SELECT (a/3)*3 AS numeric, (b/3) * 3 AS float FROM testnum;
numeric | float
99.9999999999999999 | 100
729.0000000000000000 | 729
Run Code Online (Sandbox Code Playgroud)
在这个测试中Float …
当我尝试将转储文件恢复到另一个(本地)PostgreSQL 服务器(在 Debian GNU/Linux 10.10 上运行)时,出现以下错误:
\npg_restore: error: could not execute query: ERROR: option "locale" not recognized\nRun Code Online (Sandbox Code Playgroud)\n因为它确实有以下行:
\nCREATE DATABASE "REMOTE_DB" WITH TEMPLATE = template0 ENCODING = \'UTF8\' LOCALE = \'en_GB.UTF-8\';\nRun Code Online (Sandbox Code Playgroud)\n是的,我知道PostgreSQL 12 CREATE DATABASE命令没有选项LOCALE。
我不明白的是:
\npg_dump我在本地服务器上使用的版本报告为 12.7pg_restore我在本地服务器上使用的版本报告为 12.7pg_dump是版本 12.7,而不是 13。让我一一验证一下:
\n我的本地服务器:
\n$ sudo -u postgres …Run Code Online (Sandbox Code Playgroud) 我使用的是 postgres 13.3,并且我已经有一个现有的表,其中有一GENERATED列,例如:
CREATE TABLE test_table (
id uuid NOT NULL DEFAULT uuid_generate_v4(),
the_column_to_alter bool NOT NULL GENERATED ALWAYS AS (2 > 1) STORED,
CONSTRAINT test_table2_pkey PRIMARY KEY (id)
);
Run Code Online (Sandbox Code Playgroud)
但我现在改变了主意,我希望它只是一个常规的非生成列,我可以手动编辑......
DROP创建该列这可能吗?ALTER对列执行此操作的查询是什么the_column_to_alter?
运行时:
REINDEX DATABASE CONCURRENTLY mydb;
Run Code Online (Sandbox Code Playgroud)
这可能需要几个小时,甚至几天,具体取决于数据库的大小,是否有办法粗略估计其进度?
我看到一些论坛帖子声称您可以使用如下查询来查询索引创建状态:
SELECT
now()::TIME(0),
a.query,
p.phase,
p.blocks_total,
p.blocks_done,
p.tuples_total,
p.tuples_done,
FROM pg_stat_progress_create_index p
JOIN pg_stat_activity a ON p.pid = a.pid;
Run Code Online (Sandbox Code Playgroud)
_done / _total 列与阶段相结合确实提供了粗略的进度百分比。但是,这仅列出当前更新索引的进度。它不会告诉您有多少其他索引正在等待更新,更不用说每个索引需要做多少工作了。
编辑:我尝试将 views 结合起来pg_index,其中列出了*_ccnew并发进程使用的临时索引,例如pg_stat_progress_create_index:
SELECT relname,
CASE WHEN blocks_total > 0 THEN (ci.blocks_done/ci.blocks_total::numeric*100)::int ELSE NULL END as blocks_percent,
i.*
FROM pg_class as pgc
inner join pg_index as i on i.indexrelid = pgc.oid
left outer join pg_stat_progress_create_index as ci on ci.index_relid = i.indexrelid
WHERE i.indisvalid = false; …Run Code Online (Sandbox Code Playgroud) 想象一个视图,其中包含来自两个不同表的COALESCE两varchar列。
底层证券varchars在两个表中都有索引。
在 Postgres 11.6 中,根据结果过滤此视图COALESCE不使用索引,而是进行表扫描。
但是,如果我将列更改为text,在同一列上过滤完全相同的视图,则索引将按您的预期使用。
假设我有一个一些标识符随时间变化的测量值表。还有一个几乎相同的表,其中包含估计值:
CREATE TABLE measured (
id int,
ts timestamp,
identifier character varying,
measured_value int
);
CREATE INDEX ON measured(identifier);
CREATE TABLE estimated (
id int,
ts timestamp,
identifier character varying,
estimated_value int
);
CREATE INDEX ON estimated(identifier);
Run Code Online (Sandbox Code Playgroud)
每个表有 100 万行数据:
INSERT INTO measured
SELECT
generate_series(1, 1000000),
to_timestamp((random() * 100000)::int),
left(md5(random()::text), 2),
random() * 10;
INSERT INTO estimated
SELECT
generate_series(1, 1000000),
to_timestamp((random() * …Run Code Online (Sandbox Code Playgroud) postgresql varchar execution-plan index-tuning postgresql-performance
我现在正在使用充满国际象棋游戏数据的 Postgres 数据库,其中每个游戏都是“记录”表中的一行。玩家的动作和这些动作的(可选)计算机评估都有自己的列并存储为数组。
我编写了一个查询来检索指定的开局动作序列的所有评估。(你可能认为计算机的评估会是一致的 - 但事实并非如此。)开局序列的长度是任意的 - 可以是一步,也可以是三十步。
下面是一个示例查询,它查找以相同的十步开局序列开始的所有游戏,然后对于每个带有评估的游戏,返回计算机对游戏中该点的评估 -
SELECT evaluation[10]
FROM records
WHERE moves[1:10]::text[] = ARRAY['b4', 'e5', 'Bb2', 'd6', 'Nf3', 'Nf6', 'g3', 'Bg4', 'Bg2', 'h5']::text[]
AND evaluation IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)
我不确定它是否相关,但移动数据始终是 2-6 个字符的字母数字字符串,并且计算机评估大部分是小数(正数和负数),但确实包括偶尔的特殊字符(强制将死者有一个 octothorpe前缀)。
这是表描述的相关片段 -
Column | Type |
-----------------+--------------------------------+-
id | bigint |
moves | character varying(255)[] |
evaluation | character varying(255)[] |
"records_pkey" PRIMARY KEY, btree (id)
Access method: heap
Run Code Online (Sandbox Code Playgroud)
这是来自 EXPLAIN ANALYZE 的查询计划:
Gather (cost=1000.00..736354.70 rows=905 width=516) (actual time=28251.267..28253.139 rows=0 loops=1)
Workers Planned: 2 …Run Code Online (Sandbox Code Playgroud) pg_dump 和 pg_restore 会将 search_path 设置为空字符串,如果有函数在没有显式指定模式名称的情况下调用公共模式中的函数(即:uuid_generate_v4()vs public.uuid_generate_v4()),则会失败。
我如何强制pg_restore使用指定的 search_path 例如public?
是否有某种方法可以通过 SQL 在 PostgreSQL 中创建用户/角色/组(仅当用户/角色/组尚不存在时)?到目前为止,我找到的唯一解决方案是创建自定义存储过程,因为它支持条件。有没有我忽略的更简单的解决方案?谢谢你!
postgresql ×10
index ×2
pg-dump ×2
pg-restore ×2
alter-table ×1
amazon-rds ×1
array ×1
autovacuum ×1
ddl ×1
index-tuning ×1
maintenance ×1
optimization ×1
varchar ×1