Postgres大文本搜索建议

JBe*_*Fat 6 postgresql

我对数据库很新,我正在寻找一些高级别的建议.


我正在使用Postgres 9.3构建数据库的情况在数据库中是一个表,我在其中存储日志文件.

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

内容中的文本长度可以在1k到50MB之间变化.

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

我知道索引是我的问题的解决方案,但我似乎无法创建索引 - 每当我尝试我得到索引太大的错误.

=#CREATE INDEX error_logs_content_idx ON错误日志(content text_pattern_ops);
错误:索引行需要1796232个字节,最大大小为8191

我希望就如何解决这个问题提出一些建议.我可以更改最大索引大小吗?或者,我是否应该尝试使用Postgres对文本字段进行全文搜索?

任何建议都非常感谢!

小智 4

文本搜索向量无法处理这么大的数据——请参阅记录的限制。它们的优势在于模糊搜索,因此您可以在同一调用中搜索“游泳”并找到“游泳”、“游泳”、“游泳”和“游泳”。它们并不是要取代grep.

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

如果文件中有太多唯一的单词,或者单词重复得非常频繁,那么您可能会遇到其中一个或两个限制——如果您有包含准随机数据的 50MB 日志文件,则很可能会遇到这种情况。

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

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 );
Run Code Online (Sandbox Code Playgroud)

在这里,您将每个日志行视为一个“文档”。要搜索,你会做类似的事情

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');
Run Code Online (Sandbox Code Playgroud)