我有一个助手,它正在生成一些代码来为我进行批量更新,并生成如下所示的 SQL:
( active 和 core 字段都是 type boolean
)
UPDATE fields as t set "active" = new_values."active","core" = new_values."core"
FROM (values
(true,NULL,3419),
(false,NULL,3420)
) as new_values("active","core","id") WHERE new_values.id = t.id;
Run Code Online (Sandbox Code Playgroud)
但是它失败了:
ERROR: column "core" is of type boolean but expression is of type text
我可以通过添加::boolean
空值来让它工作,但这看起来很奇怪,为什么 NULL 被认为是类型TEXT
?
此外,转换有点棘手,因为它需要对代码进行大量修改才能知道它应该将 NULL 转换为什么类型(列和值的列表目前是从一个简单的 JSON 对象数组自动生成的) .
为什么这是必要的,是否有更优雅的解决方案,不需要生成代码知道 NULL 的类型?
如果相关,我将在Node.JS上使用sequelize来执行此操作,但在 Postgres 命令行客户端中也得到相同的结果。
我正在处理一个使用instagram 密钥格式的项目。
TL;DR 64 位整数 ID。
它们将用于查找,我们也喜欢它们用于排序和批处理,因为它们会自然地按创建时间排序。
这些值介于 2^63 和 2^64 之间,因此(只是)太大而无法放入BIGINT
.
因此,我们的存储选项似乎是numeric(20)
或varchar
。varchar
不是那么理想,因为我们必须将它们归零才能进行排序才能工作,但是使用数字进行查找会影响性能吗?
我不明白为什么我们的 AWS postgres 服务器耗尽了它的所有空间。我们只需要增加分配给它的存储空间,但无法从 postgres 中找到任何关于它正在使用那么多空间的提示。
亚马逊表示,我们在过去两周内吃掉了大约 60GB。Postgres 说我们的整个数据库仅超过 5GB,数据库操作主要是 INSERT 和 SELECT。
如何追踪和回收我们的存储?
这是 PSQL 中一些 size 命令的输出
select pg_size_pretty(pg_database_size('my_db'));
-- 3730 MB
SELECT pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
AND C.relkind <> 'i'
AND nspname !~ '^pg_toast'
ORDER BY pg_total_relation_size(C.oid) DESC
LIMIT 20;
Run Code Online (Sandbox Code Playgroud)
给
1540 MB
1286 MB
235 MB
191 MB
Run Code Online (Sandbox Code Playgroud)
奇怪的是 autovacuumer 从未在任何表上触发(我假设这是因为我们很少删除行?)相对于表大小,死行的数量相当低(这些表的行数为数十万或百万)
SELECT
vacuum_count, autovacuum_count, n_dead_tup
FROM pg_stat_user_tables ORDER BY n_dead_tup …
Run Code Online (Sandbox Code Playgroud) 我试图在 Postgres 9.5 中从这个查询中挤出更多的性能。我正在运行超过 400,000 行。
在玩弄它时,我注意到这些CASE
语句增加了相当多的查询成本 - 如果我用简单地对一些现有列求和来替换它们,它会将执行时间减半。有没有更有效的方法来计算这些总和?
SELECT sum("tag1"), sum("tag2"), sum("total_tags")
FROM (
SELECT people.data->'recruiter_id' AS recruiter_id,
(CASE WHEN people.data->'tags' ? 'tag1' THEN 1 END) AS "tag1",
(CASE WHEN people.data->'tags' ? 'tag2' THEN 1 END) AS "tag2",
((CASE WHEN people.data->'tags' ? 'tag1' THEN 1 ELSE 0 END) +
(CASE WHEN people.data->'tags' ? 'tag2' THEN 1 ELSE 0 END)) AS total_tags
FROM people WHERE people.data->'tags' ?| ARRAY['tag1','tag2'] ) AS target
GROUP BY recruiter_id
Run Code Online (Sandbox Code Playgroud)
的输出EXPLAIN ANALYSE
: …
postgresql performance statistics execution-plan json postgresql-performance
postgresql ×4
amazon-rds ×1
cast ×1
datatypes ×1
index ×1
json ×1
null ×1
performance ×1
statistics ×1