gpt4 book ai didi

postgresql 不在 text 列上使用 trigram 索引,而是在 varchar 列上使用它

转载 作者:行者123 更新时间:2023-11-29 11:35:16 28 4
gpt4 key购买 nike

所以基本上我设置了一个非常简单的测试表来测试 postgresql 9.1(股票 Debian 稳定版)中的三元组和全文索引功能。

下面是表和索引定义:

-- Table: fulltextproba
-- DROP TABLE fulltextproba;
CREATE TABLE fulltextproba
(
id integer NOT NULL,
text text,
varchar600 character varying(600) COLLATE pg_catalog."C.UTF-8",
CONSTRAINT id PRIMARY KEY (id )
)
WITH (
OIDS=FALSE
);

-- Index: id_index
-- DROP INDEX id_index;
CREATE UNIQUE INDEX id_index
ON fulltextproba
USING btree
(id );

-- Index: text_gin_fulltext_hun
-- DROP INDEX text_gin_fulltext_hun;
CREATE INDEX text_gin_fulltext_hun
ON fulltextproba
USING gin
(to_tsvector('hungarian'::text, text) );

-- Index: text_gin_trgm
-- DROP INDEX text_gin_trgm;
CREATE INDEX text_gin_trgm
ON fulltextproba
USING gin
(text COLLATE pg_catalog."C.UTF-8" gin_trgm_ops);

-- Index: varchar600
-- DROP INDEX varchar600;
CREATE INDEX varchar600
ON fulltextproba
USING btree
(varchar600 COLLATE pg_catalog."C.UTF-8" varchar_pattern_ops);

-- Index: varchar600_gin_trgm
-- DROP INDEX varchar600_gin_trgm;
CREATE INDEX varchar600_gin_trgm
ON fulltextproba
USING gin
(varchar600 COLLATE pg_catalog."C.UTF-8" gin_trgm_ops);

我的问题是,如果我执行应该使用三元组索引的 %foo% 搜索,如果我在文本列上搜索,它不会:

SELECT COUNT(id) FROM public.fulltextproba WHERE text LIKE '%almáv%'
count
-------
396
(1 row)

real 0m7.215s
user 0m0.020s
sys 0m0.004s
QUERY PLAN
---------------------------------------------------------------------------
Aggregate (cost=657056.11..657056.12 rows=1 width=4)
-> Seq Scan on fulltextproba (cost=0.00..657052.72 rows=1355 width=4)
Filter: (text ~~ '%almáv%'::text)
(3 rows)

但是如果我在 varchar600 列中搜索,它会使用 trigram 索引,而且 - 毫不奇怪 - 快得多:

SELECT COUNT(id) FROM public.fulltextproba WHERE varchar600 LIKE '%almáv%'
count
-------
373
(1 row)

real 0m0.184s
user 0m0.052s
sys 0m0.004s
QUERY PLAN
--------------------------------------------------------------------------------------------
Aggregate (cost=5283.11..5283.12 rows=1 width=4)
-> Bitmap Heap Scan on fulltextproba (cost=62.50..5279.73 rows=1355 width=4)
Recheck Cond: ((varchar600)::text ~~ '%almáv%'::text)
-> Bitmap Index Scan on varchar600_gin_trgm (cost=0.00..62.16 rows=1355 width=0)
Index Cond: ((varchar600)::text ~~ '%almáv%'::text)
(5 rows)

所以最终的问题是:

  • 为什么 postgres 不在 text 列上使用 trigram 索引。
  • 如何让postgres使用索引?我应该用其他方式定义它吗?

最佳答案

text 非常好。最好的选择,正如您在 EXPLAIN 输出中看到的那样:

Index Cond: ((varchar600)::text ~~ '%almáv%'::text)

排序规则不匹配

直接原因可能是归类不匹配。您的表已定义:

text text,   -- default collation is ???
varchar600 character varying(600) COLLATE pg_catalog."C.UTF-8"

虽然两个索引都使用 COLLATE pg_catalog."C.UTF-8"。你的默认排序规则是什么?输出来自:

SHOW LC_COLLATE;

您可能会混合使用不同的排序规则。重新测试:

SELECT COUNT(id) FROM public.fulltextproba
WHERE text COLLATE pg_catalog."C.UTF-8" LIKE '%almáv%'

Read about collation support in Postgres.

测试中的一般问题

您显然在两列中有不同的值。使用相同值重复测试。

要强制 Postgres 使用索引,您可以(仅用于在您的 session 中调试!):

SET enable_seqscan = off;

然后再试一次。详情:

Postgres 9.4 中 GIN 索引的展望

即将发布的 Postgres 9.4 对 GIN 索引进行了大量改进。特别是,它们将变得更小、更快。

关于postgresql 不在 text 列上使用 trigram 索引,而是在 varchar 列上使用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25388145/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com