Производительность MySQL - Пункт "В" против Равно (=) для одного значения [дубликат]


Это довольно простой вопрос, и я предполагаю, что ответ "Это не имеет значения", но я все равно должен спросить...

У меня есть общий оператор sql, встроенный в PHP:

$sql = 'SELECT * FROM `users` WHERE `id` IN(' . implode(', ', $object_ids) . ')';

Предполагая, что до проверки достоверности ($object_ids - это массив, содержащий по крайней мере 1 элемент и все числовые значения), должен ли я вместо этого сделать следующее?

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 (если таковая вообще имеется)?

Author: JudRoman, 2012-03-29

6 answers

Ни один из них на самом деле не имеет значения в широком масштабе вещей. Задержка в сети при обмене данными с базой данных значительно перевесит либо накладные расходы count($object_ids), либо накладные расходы = по сравнению с IN. Я бы назвал это случаем преждевременной оптимизации.

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

 14
Author: mellamokb, 2012-03-29 13:36:04

Большинство других ответов не дают ничего убедительного, просто предположения. Итак, основываясь на хорошем совете из ответа @Namphibian, я запустил EXPLAIN по некоторым запросам, аналогичным тем, которые были в OP.

Результаты приведены ниже:


EXPLAIN для запроса с = 1:

Explain for a query with <code>= 1</code>


EXPLAIN для запроса с IN(1):

Explain for a query with <code>IN(1)</code>


EXPLAIN для запроса с IN(1,2,3):

Explain for a query with <code>IN(1,2,3)</code>


Как вы можете видеть, MySQL оптимизирует IN(1), чтобы быть таким же, как = 1 в такого рода запросах. Ответ @mes, похоже, указывает на то, что это не всегда может быть так с более сложными запросами, однако.

Итак, для тех, кто был слишком ленив, чтобы запустить EXPLAIN самостоятельно, теперь вы знаете. И да, вы можете захотеть запустить EXPLAIN в своем собственном запросе, чтобы убедиться, что он обрабатывается таким образом. :-)

 42
Author: J.D., 2017-09-22 21:32:55

Нет никакой разницы между инструкциями MySQL, и оптимизатор MySQL преобразует IN в =, когда IN - это всего лишь один элемент. Не беспокойтесь.

 23
Author: Konerak, 2012-03-29 13:37:16

Выполните два запроса с инструкцией explain. Это покажет вам, что делает MySQL. Вы фокусируетесь на оптимизации MySQL, которая должна быть направлена на то, что MySQL делает с запросом внутри. Пытаться оптимизировать, какой запрос выполняется, немного преждевременно.

Оба этих запроса могут быть ужасными по производительности, если, например, нет индекса. Объяснение MySQL здесь - золото. Поэтому, когда вы доберетесь до запроса, который выполняется медленно, инструкция EXPLAIN покажет вам, почему.

 8
Author: Namphibian, 2012-03-29 13:44:29

Я полагаю, что внутренне mysql будет обрабатывать запрос IN (6) точно так же, как запрос = 6, поэтому нет необходимости беспокоиться (кстати, это называется преждевременной оптимизацией)

 3
Author: Nicola Peluchetti, 2012-03-29 13:38:09

Я запускаю запрос с инструкцией explain, и вот результаты enter image description here

Очевидно, что оператор "Равно" лучше, он сканирует 13 строк, а "В" сканирует все строки

 0
Author: mes, 2014-10-09 09:43:48