我试图用GIN
构建一个非常简单的文本数组_text_ops
。我了解ts_vectors
的全部知识-出于好奇,我只想使用文本数组来完成此操作,而我在PostgreSQL 9.6中看到了一种奇怪的行为。这是我的命令序列:
drop table docs cascade;
drop index gin1;
CREATE TABLE docs (id SERIAL, doc TEXT, PRIMARY KEY(id));
-- create index gin1 on docs using gin(string_to_array(doc, ' ') _text_ops); -- before
INSERT INTO docs (doc) VALUES
('This is SQL and Python and other fun teaching stuff'),
('More people should learn SQL from us'),
('We also teach Python and also SQL');
SELECT * FROM docs;
create index gin1 on docs using gin(string_to_array(doc, ' ') _text_ops); -- after
explain select doc from docs where '{SQL}' <@ string_to_array(doc, ' ');
如果我在插入之前创建gin1
索引,则explain
会按预期工作:
pg4e=> explain select doc FROM docs WHERE '{SQL}' <@ string_to_array(doc, ' ');
Bitmap Heap Scan on docs (cost=12.05..21.53 rows=6 width=32)
Recheck Cond: ('{SQL}'::text[] <@ string_to_array(doc, ' '::text))
-> Bitmap Index Scan on gin1 (cost=0.00..12.05 rows=6 width=0)
Index Cond: ('{SQL}'::text[] <@ string_to_array(doc, ' '::text))
如果我在插入后创建gin
索引,它似乎永远不会使用该索引。
pg4e=> explain select doc from docs where '{SQL}' <@ string_to_array(doc, ' ');
Seq Scan on docs (cost=0.00..1.04 rows=1 width=32)
Filter: ('{SQL}'::text[] <@ string_to_array(doc, ' '::text))
我想知道是否是因为我需要等待一段时间才能完全填充索引(即使有四行)-但是等待几分钟并执行explain
仍然可以给我进行顺序表扫描。 / p>
然后只是为了好玩我再插入10000条记录
INSERT INTO docs (doc) SELECT 'Neon ' || generate_series(10000,20000);
explain
会显示大约10秒钟的Seq扫描,然后在10秒钟后如果我再执行一次explain
,则会显示位图堆扫描。显然,一些索引更新花了一些时间-这很有意义。但是在第一种情况下,我先插入四行然后创建索引-不管我等待explain
多长时间,都永远不会使用索引。
我有一个解决方法(在执行插入操作之前先创建索引)-我只是想知道是否存在某种机制,例如“刷新索引”或我错过了这种机制-或其他某种机制在起作用。
答案 0 :(得分:0)
说明显示Seq扫描大约10秒,然后10秒后 秒,如果我再做一次说明,则显示位图堆扫描。所以 显然,一些索引更新花了一些时间-这使得 感。但是在第一种情况下,我插入四行,然后 创建索引-无论我等待多长时间,解释都不会使用 索引。
在4行表中插入10,000行时,您超出了autovacuum_analyze_threshold和autovacuum_analyze_scale_factor确定的活动级别。因此,下次自动清理启动器访问您的数据库时,它将执行该表的ANALYZE,并使用该ANALYZE上的新数据在较大的表上确定索引扫描将很有用。但是,如果仅插入4行,则不会触发自动分析(autovacuum_analyze_threshold的默认值为50)。如果确实如此,则ANALYZE的结果将是表太小以至于索引无用,因此计划也不会改变。
我有一个解决方法(在执行插入操作之前先建立索引)
要解决该问题,您需要解决一个问题。您似乎在这里没有真正的问题(无论如何,持续时间比autovacuum_naptime更长),因此没有任何解决方法。