我有一个带有B-Tree索引的表:
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行,并决定不使用索引。鉴于类似的通配符是后缀,我认为没有理由不使用索引...
行数为:
SELECT count(*) from test_report r;
4307210
匹配行的数量非常小:
SELECT count(*) from test_report r WHERE r.accession like 'IP_%';
11094
答案 0 :(得分:5)
在许多归类中,共享相同前缀的单词可能不会按排序顺序彼此相邻。例如See here。这意味着具有这些排序规则的索引无法有效地用于完成前缀查询。
除非您的数据库归类是“C”,否则您的默认索引将无法用于前缀搜索。您可以手动指定要在支持它的索引中使用的排序规则或运算符类:
create index on foobar (x collate "C");
或
create index on foobar (x text_pattern_ops);
我只是使用“C”排序规则创建所有数据库(即使您需要使用UTF8
编码,也可以这样做)。有些人不喜欢它的排序方式,但这主要是由于区分大小写。没有人曾向我抱怨过“嘿,你需要按en_US.UTF-8排序规则排序”。这可能是因为几乎没有人知道这些规则是什么。