У меня есть следующая таблица с примерно 10 миллионами строк
CREATE TABLE "autocomplete_books"
(
id uuid PRIMARY KEY DEFAULT uuid_generate_v4 (),
author_id uuid NOT NULL REFERENCES "author"(id) ON DELETE CASCADE,
language VARCHAR(30) NOT NULL,
name VARCHAR(100) NOT NULL,
importance_rank SMALLINT NOT NULL DEFAULT 1
);
У меня есть следующий запрос
SELECT DISTINCT ON (author_id)
author_id,
similarity(name, $1) as score,
language, name, importance_rank
FROM
"autocomplete_books"
WHERE
$1 % name AND language IN ($2, $3, $4)
ORDER BY
author_id, score DESC, importance_rank DESC
LIMIT
10
Я в основном запрашиваю сходство, так как это конечная точка автозаполнения, поэтомуУ меня есть индекс триграммы по имени.Я также сортирую по некоторым другим областям.Я не уверен, как поле score
будет смешиваться с другими моими индексами и лучше ли иметь составной индекс, например,
Опция 1
CREATE INDEX ON "autocomplete_books" USING GIN (name gin_trgm_ops);
CREATE INDEX ON "autocomplete_books" USING BTREE (author_id, language, importance_rank DESC);
Или, если мне нужно разбить их так:
Вариант 2
CREATE INDEX ON "autocomplete_books" USING GIN (name gin_trgm_ops);
CREATE INDEX ON "autocomplete_books" USING BTREE (author_id, language, importance_rank DESC);
CREATE INDEX ON "autocomplete_books" USING BTREE (language);
CREATE INDEX ON "autocomplete_books" USING BTREE (importance_rank DESC);
Вот вывод explain analyze
, выполненный на 220 тыс. Строк сследующий индекс
CREATE INDEX ON "autocomplete_books" USING BTREE (author_id, language);
CREATE INDEX ON "autocomplete_books" USING BTREE (importance_rank DESC);
-
Limit (cost=762.13..762.38 rows=50 width=82) (actual time=12.230..13.024 rows=50 loops=1)
-> Unique (cost=762.13..763.23 rows=217 width=82) (actual time=12.223..12.686 rows=50 loops=1)
-> Sort (cost=762.13..762.68 rows=220 width=82) (actual time=12.216..12.373 rows=50 loops=1)
Sort Key: author_id, ((similarity((name)::text, \'sale\'::text)) DESC, importance_rank DESC
Sort Method: quicksort Memory: 45kB
-> Bitmap Heap Scan on "books_autocomplete" mat (cost=45.71..753.57 rows=220 width=82) (actual time=1.905..11.610 rows=149 loops=1)
Recheck Cond: (\'sale\'::text % (name)::text)
Rows Removed by Index Recheck: 2837
Filter: ((language)::text = ANY (\'{language1,language2,language3}\'::text[]))
Heap Blocks: exact=2078
-> Bitmap Index Scan on "books_autocomplete_name_idx" (cost=0.00..45.65 rows=220 width=0) (actual time=1.551..1.557 rows=2986 loops=1)
Index Cond: (\'sale\'::text % (name)::text)
Planning time: 13.976 ms
Execution time: 13.545 ms'