Postgres 大文本搜索建议

Postgres Large Text Search Advice

我对数据库很陌生,正在寻找一些高级建议。

情况
我正在使用 Postgres 9.3 构建数据库,数据库中有一个 table 我在其中存储日志文件。

CREATE TABLE errorlogs (
     id SERIAL PRIMARY KEY,
     archive_id INTEGER NOT NULL REFERENCES archives,
     filename VARCHAR(256) NOT NULL,
     content TEXT);

内容中的文本长度可以从 1k 到 50MB 不等。

问题
我希望能够对 "content" 列中的数据执行相当快的文本搜索(例如,WHERE CONTENT LIKE '%some_error%')。现在搜索速度非常慢(>10 分钟搜索 8206 行)。

我知道索引旨在解决我的问题,但我似乎无法创建索引——每当我尝试时,我都会收到错误消息,提示索引太大。

=# CREATE INDEX error_logs_content_idx ON errorlogs (content text_pattern_ops);
ERROR: index row requires 1796232 bytes, maximum size is 8191

我希望得到一些关于如何解决这个问题的建议。我可以更改最大索引大小吗?还是我不应该尝试使用 Postgres 对这么大的文本字段进行全文搜索?

非常感谢任何建议!

文本搜索向量无法处理这么大的数据 --- 请参阅 documented limits。他们的优势是模糊搜索,因此您可以在同一个调用中搜索 'swim' 并找到 'swim,' 'swimming,' 'swam,' 和 'swum'。它们无意取代 grep.

限制的原因在 source code 作为 MAXSTRLEN(和 MAXSTRPOS)。文本搜索向量存储在一个长的、连续的数组中,最大长度为 1 MiB(所有唯一词位的所有字符的总和)。要访问这些,ts_vector 索引结构允许 11 位的字长和 20 位的数组位置。这些限制允许索引结构适合 32 位无符号整数。

如果文件中的唯一单词过多或单词重复频率很高,则您可能 运行 处于其中一个或两个限制中 --- 如果您有 50MB 的日志文件,则很有可能准随机数据。

您确定需要将日志文件存储在数据库中吗?您基本上是在复制文件系统,greppython 可以很好地在那里进行搜索。不过,如果你真的需要,你可以考虑这个:

CREATE TABLE errorlogs (
    id SERIAL PRIMARY KEY
    , archive_id INTEGER NOT NULL REFERENCES archives
    , filename VARCHAR(256) NOT NULL
);

CREATE TABLE log_lines (
    line PRIMARY KEY
    , errorlog INTEGER REFERENCES errorlogs(id)
    , context TEXT
    , tsv TSVECTOR
);

CREATE INDEX log_lines_tsv_idx ON log_lines USING gin( line_tsv );

在这里,您将每个日志 视为一个 "document." 要搜索,您需要执行类似

SELECT e.id, e.filename, g.line, g.context
FROM errorlogs e JOIN log_lines g ON e.id = g.errorlog 
WHERE g.tsv @@ to_tsquery('some & error');