Является ли EXISTS более эффективным, чем COUNT (*)> 0? - PullRequest
26 голосов
/ 10 марта 2011

Я использую MySQL 5.1, и у меня есть запрос, который примерно имеет вид:

select count(*) from mytable where a = "foo" and b = "bar";

В моей программе проверяется только то, равно ли это нулю или не равно нулю. Если я преобразую это в:

select exists(select * from mytable where a = "foo" and b = "bar");

Достаточно ли умен MySQL, чтобы прекращать поиск при первом попадании? Или есть какой-то другой способ сообщить MySQL, что я намерен просто выяснить, соответствуют ли какие-либо записи этому, и мне не нужен точный счет?

Ответы [ 5 ]

28 голосов
/ 10 марта 2011

Да, MySQL (на самом деле все системы баз данных, насколько мне известно) прекратит обработку при возврате строки при использовании функции Exists.

Подробнее об этом можно прочитать в документации по MySQL: Если подзапрос возвращает какие-либо строки вообще, подзапрос EXISTS имеет значение ИСТИНА.

12 голосов
/ 10 марта 2011

Я запустил тест с 1000 запросов. SELECT EXISTS был примерно на 25% быстрее, чем SELECT COUNT. Добавление limit 1 к SELECT COUNT не имело никакого значения.

3 голосов
/ 10 марта 2011

Самый надежный способ - это, вероятно, LIMIT 1, но дело не в этом.

При условии, что у вас есть такой индекс, как CREATE INDEX mytable_index_a_b ON mytable (a,b), MySQL должен быть достаточно умным, чтобы возвращать счетчик из индекса и вообще не касаться каких-либо строк. Преимущество LIMIT 1, вероятно, незначительно.

Если у вас нет индекса для (a, b), производительность будет ужасной. LIMIT 1 может сделать его значительно менее ужасным, но все равно будет ужасным.

2 голосов
/ 09 декабря 2014

Это тоже может быть подход.

select 1 from mytable where a = "foo" and b = "bar" limit 1;

Это не будет проходить через все записи, которые удовлетворяют условию where, а скорее вернет '1' после первого 'нажатия'. Недостаток в том, что вам нужно проверять результат, поскольку в ответ может быть установлена ​​пустая запись.

1 голос
/ 10 марта 2011

Я не знаю, насколько хорошо это работает для оптимизации, но функционально должно работать так же, как exists.Исключением является то, что он не будет возвращать ни одной строки, если нет совпадений.

SELECT true from mytable where a = "foo" and b = "bar" LIMIT 1;
...