我们正在设计一个众所周知的读取量大的系统(每分钟读取数万次)。
names作为一种中央注册表。每行都有一个text字段representation和一个唯一的字段,key它是该字段的 MD5 哈希值representation。1该表目前有数千万条记录,预计在应用程序的生命周期内会增长到数十亿条。names表。这些表之一中的任何给定记录都保证有一个name_key,它在功能上是names表的外键。1:顺便说一句,正如您所料,此表中的记录一旦写入便不可变。
对于表以外的任何给定表names,最常见的查询将遵循以下模式:
SELECT list, of, fields
FROM table
WHERE name_key IN (md5a, md5b, md5c...);
Run Code Online (Sandbox Code Playgroud)
我想优化读取性能。我怀疑我的第一站应该是最小化索引的大小(尽管我不介意在那里被证明是错误的)。
问题:和列
的最佳数据类型是什么?
有理由使用over吗?或者?keyname_keyhex(32)bit(128)BTREEGIN
假设您有这样的nodes表:
CREATE TABLE nodes
(
node serial PRIMARY KEY,
parent integer NULL REFERENCES nodes(node),
ts timestamp NOT NULL DEFAULT now()
);
Run Code Online (Sandbox Code Playgroud)
它代表了一个标准的类似节点的树结构,根节点在顶部,几个子节点悬挂在根节点或其他子节点上。
让我们插入几个示例值:
INSERT INTO nodes (parent)
VALUES (NULL), (NULL), (NULL), (NULL), (1), (1), (1), (1), (6), (1)
, (6), (9), (6), (6), (3), (3), (3), (15);
Run Code Online (Sandbox Code Playgroud)
现在我想检索前 10 个根节点及其所有子节点,深度为 4:
WITH RECURSIVE node_rec AS
(
(SELECT 1 AS depth, * FROM nodes WHERE parent IS NULL LIMIT 10)
UNION ALL
SELECT depth + 1, n.*
FROM nodes …Run Code Online (Sandbox Code Playgroud) 我正在尝试优化一个查询,该查询在 Postgres 12.7 上从未完成。需要几个小时甚至几天的时间才能使 CPU 达到 100%,并且永远不会返回:
SELECT "id", "counter", "item_id", "item_name", "type", "updated_time"
FROM "changes"
WHERE (type = 1 OR type = 3) AND user_id = 'kJ6GYJNPM4wdDY5dUV1b8PqDRJj6RRgW'
OR type = 2 AND item_id IN (SELECT item_id FROM user_items WHERE user_id = 'kJ6GYJNPM4wdDY5dUV1b8PqDRJj6RRgW')
ORDER BY "counter" ASC LIMIT 100;
Run Code Online (Sandbox Code Playgroud)
我随机尝试使用 UNION 重写它,我相信它是等效的。基本上查询中有两部分,一部分用于 type = 1 或 3,另一部分用于 type = 2。
(
SELECT "id", "counter", "item_id", "item_name", "type", "updated_time"
FROM "changes"
WHERE (type = 1 OR type = 3) AND user_id …Run Code Online (Sandbox Code Playgroud) postgresql union postgresql-12 postgresql-performance ugly-or