Ответ 1
LIKE
без подстановочного символа эквивалентен =
. Предполагая, что вы на самом деле означали name = 'text'
.
Индексы являются ключом к производительности.
Настройка тестирования
CREATE TABLE image (
image_id serial PRIMARY KEY
, group_id int NOT NULL
, name text NOT NULL
);
В идеале вы создаете два индекса (помимо первичного ключа):
CREATE INDEX image_name_grp_idx ON image (name, group_id);
CREATE INDEX image_grp_idx ON image (group_id);
Вторые могут не понадобиться, в зависимости от распределения данных и других деталей. Объяснение здесь:
Query
Это должен быть самый быстрый запрос для вашего случая:
SELECT * FROM image WHERE name = 'name105' AND group_id = 10
UNION ALL
SELECT * FROM image WHERE name = 'name105'
UNION ALL
SELECT * FROM image WHERE group_id = 10
LIMIT 1;
Предложение LIMIT
применяется ко всему запросу. Postgres достаточно умный не выполнять более поздние ножки UNION ALL
, как только он найдет достаточно строк, чтобы удовлетворить LIMIT
. Следовательно, для совпадения в первом SELECT
запроса вывод EXPLAIN ANALYZE
выглядит следующим образом (прокрутите вправо!):
Limit (cost=0.00..0.86 rows=1 width=40) (actual time=0.045..0.046 rows=1 loops=1) Buffers: local hit=4 -> Result (cost=0.00..866.59 rows=1002 width=40) (actual time=0.042..0.042 rows=1 loops=1) Buffers: local hit=4 -> Append (cost=0.00..866.59 rows=1002 width=40) (actual time=0.039..0.039 rows=1 loops=1) Buffers: local hit=4 -> Index Scan using image_name_grp_idx on image (cost=0.00..3.76 rows=2 width=40) (actual time=0.035..0.035 rows=1 loops=1) Index Cond: ((name = 'name105'::text) AND (group_id = 10)) Buffers: local hit=4 -> Index Scan using image_name_grp_idx on image (cost=0.00..406.36 rows=500 width=40) (never executed) Index Cond: (name = 'name105'::text) -> Index Scan using image_grp_idx on image (cost=0.00..406.36 rows=500 width=40) (never executed) Index Cond: (group_id = 10) Total runtime: 0.087 ms
Смелый акцент мой.
Не добавляйте предложение ORDER BY
, это лишает эффект. Затем Postgres должен будет рассмотреть все строки перед возвратом верхней строки.
Заключительные вопросы
Существует ли для этого общее решение?
Это общее решение. Добавьте столько операторов SELECT
, сколько хотите.
Конечно, это пригодится, когда результат поиска будет отсортирован по его релевантности.
В результате с LIMIT 1
есть только одна строка. Вид сортировки пустот.