Какой наиболее эффективный способ выбрать несколько строк по набору из 100 тысяч идентификаторов в sql

#mysql #sql

#mysql #sql

Вопрос:

Я знаю, что вы можете использовать

 SELECT * 
  FROM table 
 WHERE id IN (ids)
 

В моем случае у меня 100 000 идентификаторов.

Мне интересно, есть ли у MySQL ограничение для предложения IN. Если кто-нибудь знает более эффективный способ сделать это, это было бы здорово!

Спасибо!

Комментарии:

1. MySQL должен быть достаточно эффективным с большим IN предложением (он сортирует значения и использует двоичный поиск).

Ответ №1:

Только на этой неделе у меня был kill -9 сервер MySQL 5.7, где один из разработчиков выполнил запрос, подобный описанному вами, со списком из сотен тысяч идентификаторов в IN( ) предикате. Это привело к зависанию потока, выполняющего запрос, и он даже не ответил на KILL команду. Мне пришлось принудительно закрыть экземпляр сервера MySQL.

(К счастью, это был всего лишь тестовый сервер.)

Поэтому я рекомендую не делать этого. Я бы рекомендовал один из следующих вариантов:

  1. Разделите свой список из 100 000 идентификаторов на пакеты не более 1000 и запустите запрос для каждого пакета. Затем используйте код приложения для объединения результатов.
  2. Создайте временную таблицу с целочисленным первичным ключом.
     CREATE TEMPORARY TABLE mylistofids (id INT PRIMARY KEY);
     

    ВСТАВЬТЕ в него 100 000 идентификаторов. Затем запустите запрос ОБЪЕДИНЕНИЯ, например:

     SELECT t.* FROM mytable AS t JOIN mylistofids USING (id)
     

Ответ №2:

Предложения Билла Карвина хороши.

Количество значений из предложения IN ограничено только max_allowed_packet из my.ini

MariaDB создает временную таблицу, когда предложение IN превышает 1000 значений.

Другой проблемой с таким количеством идентификаторов является передача данных из PHP-скрипта (например) на сервер MySQL. Это будет очень длинный запрос. Вы также можете создать хранимую процедуру с этим select и просто вызвать ее из своего скрипта. Это будет более эффективно с точки зрения передачи данных из вашего скрипта в MySQL.