У меня есть простая таблица, созданная следующим образом:
CREATE TABLE IF NOT EXISTS "public"."bench2" (
"tags_text_1" text[],
"tags_text_2" text[]
)
И у меня есть индекс для первого столбца, созданного так:
CREATE INDEX "idx_tags_text_1" ON "public"."bench2" USING gin ("tags_text_1")
Я вставляю 15 миллионов строк с 1-10 случайными строками в качестве тегов tag1, tag2, ..., tag10 и вставляю одинаковые элементы в оба столбца, поэтому tags_text_1 всегда совпадает с tags_text_2
Я использую Postgres на своем Mac Book Pro 2017 года, версия:
PostgreSQL 10.5 on x86_64-apple-darwin14.5.0, compiled by Apple LLVM version 7.0.0 (clang-700.1.76), 64-bit
Я пытаюсь запросить два поля следующим образом:
SELECT count(*) from bench2 WHERE tags_text_1 && ARRAY['tag1']
Объяснять
SELECT count(*) from bench2 WHERE tags_text_2 && ARRAY['tag1']
Объясните
Эти два запроса не используют индекс и занимают 4 секунды каждый
SELECT count(*) from bench2 WHERE tags_text_1 @> ARRAY['tag1']
Объяснять
SELECT count(*) from bench2 WHERE tags_text_2 @> ARRAY['tag1']
Объяснять
Эти два запроса не используют индекс и занимают 4 секунды каждый
SELECT count(*) from bench2 WHERE tags_text_1 <@ ARRAY['tag1']
Объяснять
SELECT count(*) from bench2 WHERE tags_text_2 <@ ARRAY['tag1']
Объяснять
Первый использует индекс и занимает 8,5 секунды, а второй не использует индекс и занимает 2,8 секунды.
Я не понимаю. Почему только оператор <@ использует индекс? И почему запрос, использующий индекс, дольше всего выполняется?
Я пытаюсь оптимизировать запросы для поиска строки, в которой теги соответствуют как минимум одному тегу, поэтому &&.
Есть идеи, что происходит? Есть ли конфигурация PostgreSQL, о которой я должен знать (размер индекса составляет 100 МБ для 15 миллионов записей). Я должен признать, что я немного потерян. </p>