假设一个items
像这样的 postgresql 表。(keywords
列是类型text[]
)
name account_id keywords
------------------------------
foo1 1 ['k1', 'k2']
foo2 1 ['k1', 'k3']
foo3 2 ['k4', 'k1']
foo4 2 ['k1', 'k6']
Run Code Online (Sandbox Code Playgroud)
items 中的每一行都与 a 相关Account
(该表由 account_id 虚拟拆分)。我们希望进行如下查询:“带有关键字 k1 的帐户 1 的项目”。此查询需要在account_id
和keywords
列上使用复合 GIN 索引。
实际上,我们需要一个倒排索引,行是这样的:(每行的键应该是复合的)
(account_id, keyword) --> [item1, item2, ...]
在 postgresql 中创建此索引的正确方法是什么?
我有一个存储一些多语言内容的表:
CREATE TABLE search (
content text NOT NULL,
language regconfig NOT NULL,
fulltext tsvector
);
CREATE INDEX search_fulltext ON search USING GIN(fulltext);
INSERT INTO search (language, content) VALUES
('dutch', 'Als achter vliegen vliegen vliegen vliegen vliegen vliegen achterna'),
('dutch', 'Langs de koele kali liep een kale koeli met een kilo kali op zijn kale koeli-kop.'),
('dutch', 'Moeder sneed zeven scheve sneden brood'),
('english', 'I saw Susie sitting in a shoe shine shop. Where she sits she shines, and where …
Run Code Online (Sandbox Code Playgroud) 无法O (log n)
及时索引和执行查询。
该查询包括一个INNER JOIN
、一个ORDER BY
和一个相等运算。如果我正确理解了数据库的规律,O (log n)
如果一个非等式运算符没有在多于一列上使用,则可以及时(或大约)索引和执行查询。在这种情况下,我相信INNER JOIN
确实算作相等运算符,而非相等运算符将是ORDER BY
查询的一部分。该表有超过 10,000,000 行,需要每秒处理多次读取和写入。
使用 PostgreSQL。这就是桌子的样子。如您所见,“Names”列是一个列表属性,它是与之相反的列INNER JOIN
:
Age Names Date
34 ['carla', 'john', 'sam'] 3/13/2011
26 ['json', 'cindy', 'joel'] 3/13/2011
72 ['beth', 'amber', 'susie'] 3/13/2011
14 ['john', 'jim', 'debie'] 3/13/2011
Run Code Online (Sandbox Code Playgroud)
这是我们尝试执行的查询:
SELECT * FROM the_table WHERE Age==26 AND Names=='john' ORDER BY Date
Run Code Online (Sandbox Code Playgroud)
我的背景来自使用 App Engine 的 Big Table,所以我在这里使用了相等运算符来指示它'john'
应该是Names
列中的名称之一。这将是 GAE 大表中可接受的查询,它将O (log N)
及时执行,因为所有大表查询都需要执行。我假设在 …
我正在使用带有 *pg_trgm* 扩展名的 Postgresql 9.1。我需要在基于文本的字段上创建索引。我不需要全文搜索,我使用ILIKE
查询来进行搜索。
我会用pg_trgm
,但不具有太多的经验gin
和gist
索引。我会有很多INSERT
报表(每天约 15000 条)和很少的UPDATE
报表(可能是一周内 1 条或 2 条)。
gin
此类表上的索引的索引更新开销是多少?还是gist
更合适?
我在基于 SSD 的四核虚拟专用服务器 (VPS) 和 Debian Linux (8) 上运行 PostgreSQL 9.4.15。相关表有大约 200 万条记录。
记录经常被插入,甚至更频繁地(不断——至少每隔几秒钟)更新一次。据我所知,我已经为这些操作准备了所有适当的索引,以便快速执行,而且绝大多数时间它们确实会立即执行(以毫秒为单位)。
然而,每隔一小时左右,其中一个UPDATE
查询就会花费过多的时间——比如 10 秒或更长时间。当这种情况发生时,它通常就像“一批”被“阻塞”的查询,几乎同时终止。就好像其中一个查询或其他一些后台操作(例如,真空)正在阻止它们。
表 ,items
有很多列,但我认为以下是唯一可能与问题相关的列:
id INTEGER NOT NULL
(首要的关键)search_vector TSVECTOR
last_checkup_at TIMESTAMP WITHOUT TIME ZONE
这些是相关的索引:
items_pkey PRIMARY KEY, btree (id)
items_search_vector_idx gin (search_vector)
items_last_checkup_at_idx btree (last_checkup_at)
最后,当pg_stat_activity
我的日志文件中发出“连接泄漏”警告时,在组装了一个小脚本以转储(所有活动 Postgres 连接/查询的列表)的内容后,我缩小了可能的罪魁祸首查询/列(假设问题不是外部的,比如行为不端的 VPS)。粗略地说,这些查询似乎一次又一次地出现:
UPDATE items SET last_checkup_at = $1 WHERE items.id = 123245
UPDATE items SET search_vector = [..] WHERE items.id = 78901
这些略有解释,但我真的怀疑缺少任何相关内容。偶尔也会出现其他查询(在其他表上),但这些查询通常看起来只是“不走运”而被卷入其中。
现在,即使第一个查询(设置last_checkup_at …
postgresql performance index gin-index postgresql-performance