我有这个 Postgres 功能。它强制文本为小写,所有空值变为空字符串,以便我更干净地执行搜索不匹配的内容等:
CREATE OR REPLACE FUNCTION magic_text(txt text) RETURNS text
IMMUTABLE PARALLEL SAFE
LANGUAGE SQL AS $$
SELECT lower(coalesce(txt,''))
$$;
Run Code Online (Sandbox Code Playgroud)
这个函数在许多不同的查询类型中被大量使用,所以我为它创建了所有种类的文本索引:
CREATE INDEX index_magic_cards_on_oracle_text_magic
ON magic_cards
USING BTREE (magic_text(oracle_text)) WITH (fillfactor = 100);
CREATE INDEX index_magic_cards_on_oracle_text_magic_text_pattern
ON magic_cards
USING BTREE (magic_text(oracle_text) text_pattern_ops) WITH (fillfactor = 100);
CREATE INDEX index_magic_cards_on_oracle_text_magic_gist_trgm
ON magic_cards
USING GIST (magic_text(oracle_text) gist_trgm_ops);
CREATE INDEX index_magic_cards_on_oracle_text_magic_gin_trgm
ON magic_cards
USING GIN (magic_text(oracle_text) gin_trgm_ops)
Run Code Online (Sandbox Code Playgroud)
这些索引以某种方式干扰了某些(但不是全部)类型的复杂正则表达式搜索。我无法确定特定的正则表达式符号或功能是否会导致问题。
这是一个示例(explain.depesz):
SELECT card_name
FROM magic_cards
WHERE magic_text(oracle_text) ~ '***:(?n)eldrazi\ (?!scion)';
Run Code Online (Sandbox Code Playgroud)
这不返回任何内容,并且根据查询规划器,它会在 上执行位图索引扫描 …