postgresql不在text列上使用trigram索引,但在varchar列上使用它
所以基本上我设置了一个非常简单的测试表来测试
postgresql 9.1(股票Debian stable)中的trigram和全文索引功能.
以下是表和索引定义: -- 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%搜索应该使用trigram索引,如果我搜索文本列,它不会: 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不在文本列上使用trigram索引. 解决方法
文字很好.甚至是最好的选项,正如您在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使用索引,您可以(仅用于在会话中进行调试!): SET enable_seqscan = off; 然后再试一次.细节: > Left Join Lateral and array aggregates Postgres 9.4中的GIN指数展望 即将发布的Postgres 9.4随GIN索引进行了大量改进.特别是,它们将变得更小更快. > GIN index in the release notes for 9.4. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- c# – Roslyn的“.WithFooToken()”调用是多余的吗?
- swift tuple多元组
- Flex开发实例教程-基于RED5 Flex流媒体应用实战开发
- 如何做自定义Loading加载其它swf
- Flashback feature for MySQL
- 尝试在VB .NET中执行DTS包时“无效的类字符串”
- c# – Marshal.GetActiveObject(“Outlook.Application”)在
- 关于cocos2dx widget窗口中的关闭按钮 删除自身 的时候崩溃
- 优化AJAX提交到Handler的ProcessRequest方法
- c# – ServerCertificateValidationCallback被忽略