Обсуждение: Вопрос по intarrays и GIN/GIST индексам
Собственно первый вопрос почему GIN индексы по intarray на postgres 8.3 просто не работают :(
vision=# \d vision_video
Таблица "public.vision_video"
Колонка | Тип | Модификаторы
-------------+-----------------------------+-----------------------------------------------------------------------
id | integer | not null default nextval(('public.documents_id_seq'::text)::regclass)
class | character varying(48) | not null
topic | integer[] |
...
vision=# SELECT count(*) from vision_video;
count
-------
90384
(1 запись)
vision=# CREATE INDEX CONCURRENTLY vision_video_topic_idx ON vision_video USING GIN(topic);
CREATE INDEX
vision=# EXPLAIN ANALYZE SELECT * FROM vision_video WHERE topic && ARRAY['112']::integer[];
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Seq Scan on vision_video (cost=0.00..16569.67 rows=90 width=1248) (actual time=0.089..142.912 rows=990 loops=1)
Filter: (topic && ('{112}'::text[])::integer[])
Total runtime: 147.815 ms
(3 rows)
там же через минуту:
vision=# CREATE INDEX CONCURRENTLY vision_video_topic1_idx ON vision_video USING GIST(topic);
CREATE INDEX
vision=# EXPLAIN ANALYZE SELECT * FROM vision_video WHERE topic && ARRAY['112']::integer[];
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------
Index Scan using vision_video_topic1_idx on vision_video (cost=0.00..112.24 rows=90 width=1248) (actual
time=0.084..7.374rows=990 loops=1)
Index Cond: (topic && ('{112}'::text[])::integer[])
Total runtime: 12.186 ms
(3 rows)
Это первое... по логике GIN индекс должен быть быстрее но этого не наблюдается и он вообще не желает использоваться.
(analyze/reindex ситуацию не меняют)
Второе:
На аналогичной таблице имеем еще один intarray со следующими данными:
Опять же:
vision=# SELECT count(*) from vision_video;
count
-------
90384
(1 запись)
vision=# SELECT count(*) from vision_video where tags is not null and tags <> '{}';
count
-------
18115
(1 запись)
(тоесть совсем не много реально заполненных данных)
Средняя длинна тагов тоже маленькая:
vision=# SELECT avg(array_upper(tags,1)) from vision_video where tags is not null and tags <> '{}';
avg
--------------------
2.6531603643389456
(1 запись)
Совсем уникальных записей
vision=# SELECT count(distinct tags) from vision_video where tags is not null and tags <> '{}';
count
-------
10398
(1 запись)
GIN индекс по этому полю делается за 1-10 секунд... но не работает... см п1.
Создание же GIST индекса занимает черт знает сколько времени (сейчас уже вот 4 часа на серьезном сервере работает и
грузитодно ядро на 100%).
Что делать и как вылечить ситуацию (записей смешное количество)?
--
Maxim Boguk
On Thu, 20 Mar 2008, Maxim Boguk wrote:
> Собственно первый вопрос почему GIN индексы по intarray на postgres 8.3
> просто не работают :(
а зачем тебе intarray ?
В 8.3 это тебе не нужно.
postgres=# \d tt
Table "public.tt"
Column | Type | Modifiers
--------+-----------+-----------
a | integer[] |
Indexes:
"gin_idx" gin (a)
postgres=# explain analyze select * from tt where a && '{112}';
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on tt (cost=88.29..1417.98 rows=500 width=231) (actual time=2.406..9.584 rows=9547 loops=1)
Recheck Cond: (a && '{112}'::integer[])
-> Bitmap Index Scan on gin_idx (cost=0.00..88.17 rows=500 width=0) (actual time=1.821..1.821 rows=9547 loops=1)
Index Cond: (a && '{112}'::integer[])
Total runtime: 13.194 ms
(5 rows)
>
> Второе:
> На аналогичной таблице имеем еще один intarray со следующими данными:
>
> GIN индекс по этому полю делается за 1-10 секунд... но не работает... см п1.
>
> Создание же GIST индекса занимает черт знает сколько времени (сейчас уже вот
> 4 часа на серьезном сервере работает и грузит одно ядро на 100%).
> Что делать и как вылечить ситуацию (записей смешное количество)?
http://www.postgresql.org/docs/current/static/intarray.html
Two GiST index operator classes are provided: gist__int_ops (used by default) is suitable for small and medium-size
arrays,while gist__intbig_ops uses a larger signature and is more suitable for indexing large arrays.
В твоем случае надо использовать gist__intbig_ops
Regards,
Oleg
_____________________________________________________________
Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
Sternberg Astronomical Institute, Moscow University, Russia
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(495)939-16-83, +007(495)939-23-83