Postgresql 为什么postgres不使用BTree索引作为like';常量前缀u%';标准

Postgresql 为什么postgres不使用BTree索引作为like';常量前缀u%';标准,postgresql,Postgresql,我有一个带有B树索引的表: CREATE INDEX idx_test_report_accession on test_report (accession); 我使用explain运行以下查询: "QUERY PLAN" "Seq Scan on public.test_report r (cost=0.00..705829.12 rows=30694 width=1140) (actual time=0.143..6253.818 rows=11094 loops=1)" " Outp

我有一个带有B树索引的表:

CREATE INDEX idx_test_report_accession on test_report (accession);
我使用explain运行以下查询:

"QUERY PLAN"
"Seq Scan on public.test_report r  (cost=0.00..705829.12 rows=30694 width=1140) (actual time=0.143..6253.818 rows=11094 loops=1)"
"  Output: detected_transcript_translation_id, peptide_spectrum_match_id, accession, peptide, modified_sequence, var_mod, spectrum_title, spectrum_file, confidence, mz, retention_time, precursor_mz_error_ppm, sample_name, transcript, gene_symbol, prot_seq, ref_based_location, external_identifier, experiment_name, report_filename, line_number, experiment_path"
"  Filter: (r.accession ~~ 'IP_%'::text)"
"  Rows Removed by Filter: 4296116"
"Planning time: 1.331 ms"
"Execution time: 6255.560 ms"
它似乎认为表中只有30694行,并决定不使用索引。鉴于like通配符是后缀,我认为没有理由不使用索引

行计数为:

SELECT count(*) from test_report r;
4307210
匹配行的数量非常少:

SELECT count(*) from test_report r WHERE r.accession like 'IP_%';
11094
笔记:
  • Postgres版本是9.4

在许多排序规则下,共享相同前缀的单词可能不会按排序顺序相邻出现。例如这意味着具有这些排序规则的索引不能有效地用于完成前缀查询

除非数据库排序规则为“C”,否则默认索引将无法用于前缀搜索。您可以手动指定排序规则或运算符类,以便在支持它的索引中使用:

create index on foobar (x collate "C");


我只是使用“C”排序规则创建所有数据库(即使需要使用
UTF8
编码,也可以这样做)。有些人不喜欢它的分类方式,但这主要是因为区分大小写。从来没有人向我抱怨过“嘿,你需要按照en_US.UTF-8排序规则进行排序”。这可能是因为几乎没有人知道这些规则是什么。

请显示
explain(analyze,verbose)
的输出。还有:你的确切版本是什么?
create index
@a\u horse:有什么变化吗?据我所知,
text\u pattern\u ops
对于Unicode整理的字段仍然是必需的。感谢@a\u horse\u with\u no\u name,我增加了解释的详细性,并按照您的建议添加了pg版本(9.4)
create index on foobar (x text_pattern_ops);