Производительность MySQL - позиция "IN" против равных (=) для одного значения
Это довольно простой вопрос, и я предполагаю, что ответ "Это не имеет значения", но я все равно должен спросить...
У меня есть общий оператор sql, встроенный в PHP:
$sql = 'SELECT * FROM `users` WHERE `id` IN(' . implode(', ', $object_ids) . ')';
Предполагая предыдущие проверки достоверности ($object_ids
- это массив с не менее чем одним элементом и всеми численными значениями), следует ли вместо этого сделать следующее:
if(count($object_ids) == 1) {
$sql = 'SELECT * FROM `users` WHERE `id` = ' . array_shift($object_ids);
} else {
$sql = 'SELECT * FROM `users` WHERE `id` IN(' . implode(', ', $object_ids) . ')';
}
Или это накладные расходы на проверку count($object_ids)
не стоит того, что было бы сохранено в фактическом sql-заявлении (если оно вообще есть)?
Ответы
Ответ 1
Ни один из них не имеет большого значения в большом объеме вещей. Задержка в сети при общении с базой данных значительно перевешивает либо служебные данные count($object_ids)
, либо служебные данные =
vs IN
. Я бы назвал это случаем преждевременной оптимизации.
Вы должны профилировать и загружать тестовое приложение, чтобы узнать, где находятся настоящие узкие места.
Ответ 2
Большинство других ответов не дают ничего убедительного, просто спекуляции. Итак, основываясь на хорошем совете из ответа @Namphibian, я запускал EXPLAIN
для некоторых запросов, подобных тем, которые есть в OP.
Ниже приведены результаты:
EXPLAIN
для запроса с = 1
:
![Объясните для запроса с <code> = 1 </code>]()
EXPLAIN
для запроса с IN(1)
:
![Объясните для запроса с <code> IN (1) </code>]()
EXPLAIN
для запроса с IN(1,2,3)
:
![Объясните для запроса с <code> IN (1,2,3) </код >]()
Как вы можете видеть, MySQL оптимизирует IN(1)
, чтобы быть таким же, как = 1
в этом типе запроса. @mes answer, похоже, указывает, что это может не всегда быть в случае с более сложными запросами.
Итак, для тех, кто был слишком ленив, чтобы запустить EXPLAIN
себя, теперь вы знаете. И да, вы можете запустить EXPLAIN
в своем собственном запросе, чтобы убедиться, что он обработан таким образом.: -)
Ответ 3
Нет никакой разницы между операторами MySQL, и оптимизатор MySQL преобразует IN в = когда IN является всего лишь одним элементом. Не беспокойтесь.
Ответ 4
Запустите два запроса с помощью инструкции объяснения. Это покажет вам, что делает MySQL. Вы сосредотачиваетесь на оптимизации MySQL, должно быть на том, что делает MySQL с внутренним запросом. Попытка оптимизировать, какой запрос выполняется, немного преждевременна.
Оба эти запроса могут быть ужасными в производительности, если нет индекса, например. Инструкция MySQL EXPLAIN здесь золото. Поэтому, когда вы дойдете до запроса, который работает медленно, оператор EXPLAIN покажет вам, почему.
Ответ 5
Я предполагаю, что внутренне mysql будет обрабатывать запрос IN (6)
точно как запрос = 6
, поэтому нет необходимости беспокоиться (кстати, это называется преждевременной оптимизацией)
Ответ 6
Я запускаю запрос с объяснением, и вот результаты
![enter image description here]()
Очевидно, что оператор "Equals" лучше, он сканирует 13 строк, а "IN" просматривает все строки