Где запрос быстрее с IN или подзапросом к другой таблице? - PullRequest
0 голосов
/ 29 сентября 2018

Представьте, что у вас есть таблица "users", которая содержит 100 000 записей, и вам нужно найти 3000 элементов по идентификатору.

Быстрее ли выполнить этот запрос с помощью

Select * from users where id IN (2,5,30,89,...) # 3000 items

илибыло бы быстрее сохранить эти 3000 элементов в другой таблице и выполнить подзапрос, например:

Select * from users where id IN (select distinct id from lookuptable)
# lookuptable contains the 3000 records

Или это полностью то же самое?Спасибо!

Ответы [ 3 ]

0 голосов
/ 29 сентября 2018

В PostgreSQL самый быстрый способ - создать таблицу поиска и выполнить запрос следующим образом:

SELECT * FROM users AS u
WHERE EXISTS (SELECT 1 FROM lookuptable AS l
              WHERE u.id = l.id);
0 голосов
/ 29 сентября 2018

Я создал базу данных с требованиями и протестировал ее.С точки зрения «времени», на самом деле нет никакой разницы, но, возможно, это потому, что моя тестовая среда песочницы.

В любом случае, я «объяснил» эти запросы к дереву:

1- select * from users where id in (1,2,3,4,5,6,7,8,9,10,..3000)

стоимость: "Сканирование индекса с использованием user_pkey для пользователей ( стоимость = 4.04..1274.75 строк = 3000 ширина = 11)" "Индекс Cond: (id = ANY ('{1,2, 3,4,5,6,7,8,9,10 (...) "

2- SELECT * FROM users AS u WHERE EXISTS (SELECT 1 FROM lookuptable A-- l WHERE u.id = l.id); <- <em>Обратите внимание, что я удалил" отличную ", этобесполезно.

стоимость: "Слияние Полу Соединение ( стоимость = 103.22..364.35 строк = 3000 ширина = 11)"

"Слияние Cond: (u.id = l.id) "

" -> Сканирование индекса с использованием user_pkey для пользователей u ( стоимость = 0.29..952.68 строк = 30026 ширина = 11) "

"-> Сканирование индекса с использованием users_pkey для пользователей u ( стоимость = 0.29..952.68 строк = 30026 ширина = 11)"

3- Select * from users where id IN (select id from lookuptable)

"Слияние с половиной объединения ( стоимость = 103.22..364.35 строк = 3000 ширина = 11) "

" Конвертер слияния: (users.id = lookuptable.id) "

"-> Сканирование индекса с использованием users_pkею для пользователей ( стоимость = 0,29..952.68 строк = 30026 ширина = 11) "

" -> Сканирование только по индексу с использованием lookuptable_pkey для таблицы поиска ( стоимость = 0,28..121.28 строк = 3000 width = 4) "

Графическое объяснение двух последних запросов:

This is the explain graiphic of the last two


В любом случае, как я читал в некоторых комментариях выше, вы также должны добавить к стоимости запросов затраты на заполнение таблицы поиска ... а также тот факт, что вам нужно разделить «запрос» наразличные исполнения, которые могут вызвать «транзакционные проблемы».Я буду использовать первый запрос.

0 голосов
/ 29 сентября 2018

Лучший способ выяснить это - использовать анализ объяснения для рабочего набора данных. sql объяснение Он покажет вам время выполнения запроса и маршрут запроса.

Оптимизатор запросов может использовать различные методы в зависимости от размера таблицы, настроек базы данных, настроек памяти и т. Д.

Если в справочной таблице только 3000 записей, вам не нужны отдельные записи, если она действительно большая и имеет гораздо больше записей и создает 3000 уникальных записей, тогда первое решение может быть быстрее.

...