Является ли EXISTS более эффективным, чем COUNT (*)> 0?
Я использую 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, что я намерен просто выяснить, соответствуют ли какие-либо записи, и мне не нужен точный счет?
Ответы
Ответ 1
Да, MySQL (действительно, все системы баз данных, насколько мне известно) прекратит обработку, когда строка будет возвращена при использовании функции Exists.
Более подробную информацию вы можете найти в документации по MySQL:
Если подзапрос возвращает любые строки вообще, подзапрос EXISTS имеет значение ИСТИНА.
Ответ 2
Я провел тест с 1000 запросами. SELECT EXISTS
был примерно на 25% быстрее, чем SELECT COUNT
. Добавление limit 1
в SELECT COUNT
не имело никакого значения.
Ответ 3
Самый надежный способ, вероятно, LIMIT 1
, но это не точка.
Если у вас есть индекс типа CREATE INDEX mytable_index_a_b ON mytable (a,b)
, MySQL должен быть достаточно умным, чтобы возвращать счетчик из индекса и вообще не касаться каких-либо строк. Преимущество LIMIT 1, вероятно, незначительно.
Если у вас нет индекса на (a, b), производительность будет ужасной. LIMIT 1 может сделать его значительно менее страшным, но все равно будет страшно.
Ответ 4
Это тоже может быть подход.
select 1 from mytable where a = "foo" and b = "bar" limit 1;
Это не будет трассировать все записи, которые удовлетворяют условию where, а скорее возвращают "1" после первого "удара".
Недостатком является то, что вам нужно проверить результат, потому что взамен может быть пустая запись.
Ответ 5
Я не знаю, насколько хорошо это работает для оптимизации, но оно должно функционировать так же, как exists
. Исключение состоит в том, что он не вернет строку, если нет совпадения.
SELECT true from mytable where a = "foo" and b = "bar" LIMIT 1;