有没有办法有效地索引包含正则表达式模式的文本列?

时间:2015-12-29 05:07:53

标签: regex postgresql indexing pattern-matching operators

我正在使用PostgreSQL,目前版本为9.2,但我愿意升级。

在我的一个表中,我有一个类型SCRIPTLOC = os.path.dirname(__file__) TESTBASELINE = os.path.join(SCRIPTLOC, 'baseline', 'baseline.csv') baseline = pandas.DataFrame.from_csv(TESTBASELINE) 的列,用于存储正则表达式模式。

text

然后我就这样查询:

CREATE TABLE foo (
    id serial,
    pattern text,
    PRIMARY KEY(id)
);
CREATE INDEX foo_pattern_idx ON foo(pattern);

我知道这是一种反向INSERT INTO foo (pattern) VALUES ('^abc.*$'); SELECT * FROM foo WHERE 'abc literal string' ~ pattern; 或反向模式匹配。如果它是另一种更常见的方式,如果我的干草堆在数据库中,并且我的针被锚定,我可以根据确切的搜索模式和数据或多或少地使用btree索引。

但我拥有的数据是一个模式表和与模式相关的其他数据。我需要询问数据库哪些行具有与我的查询文本匹配的模式。有没有办法使这比检查表中每一行的顺序扫描更有效?

1 个答案:

答案 0 :(得分:2)

没办法

索引需要IMMUTABLE个表达式。表达式的结果取决于输入字符串。除了评估每一行的表达式之外,我没有看到任何其他方式,这意味着顺序扫描。

相关答案以及IMMUTABLE角度的更多详细信息:

只是没有针对您的案例的解决方法,不可能进行索引。索引需要在其元组中存储常量值,这是不可用的,因为每行的结果值是根据输入计算的。如果不查看列值,就无法转换输入。

Postgres索引用法绑定到运算符,并且只能使用运算符的表达式 left 上的索引(由于相同的逻辑约束)。更多:

许多运算符定义COMMUTATOR,它允许查询计划器/优化器将索引表达式翻转到左侧。简单示例:=的换向器为=>的换向器是<,反之亦然。 The documentation:

  

索引扫描机制希望看到运算符左侧的索引列。

正则表达式匹配运算符 ~ 再次没有换向器,因为这是不可能的。亲眼看看:

SELECT oprname, oprright::regtype, oprleft::regtype, oprcom
FROM   pg_operator
WHERE  oprname = '~'
AND    'text'::regtype IN (oprright, oprleft);

 oprname | oprright |  oprleft  | oprcom
---------+----------+-----------+------------
 ~       | text     | name      | 0
 ~       | text     | text      | 0
 ~       | text     | character | 0
 ~       | text     | citext    | 0

And consult the manual here:

  

oprcom ...此运营商的换向器,如果有的话   ...
  未使用的列包含零。例如,oprleft对于前缀运算符为零。

我以前曾尝试过并且不得不接受 上的