Я пытаюсь выяснить, существует ли строка в таблице. Используя MySQL, лучше сделать запрос следующим образом:
SELECT COUNT(*) AS total FROM table1 WHERE ...
и проверьте, если сумма не равна нулю или лучше сделать запрос, как это:
SELECT * FROM table1 WHERE ... LIMIT 1
и проверить, были ли возвращены какие-либо строки?
В обоих запросах предложение WHERE использует индекс.
sql
mysql
performance
exists
Бернард Чен
источник
источник
...EXISTS( SELECT 1/0 FROM someothertable)
. Для SQL Server и Oracle - нет разницы, использовать *, 1 или NULL, потому что EXISTS проверяет только логическое значение на основе 1+ соответствия критерия WHERE.SELECT 1 FROM table1 WHERE col = $var LIMIT 1
быстрее, чем ваш запрос. Так в чем же преимущество вашего запроса?Я недавно провел несколько исследований на эту тему. Способ его реализации должен быть другим, если это поле TEXT, неуникальное поле.
Я сделал несколько тестов с полем TEXT. Учитывая тот факт, что у нас есть таблица с 1М записей. 37 записей равны «чему-то»:
SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1
сmysql_num_rows()
: 0,039061069488525 с. (БЫСТРЕЕ)SELECT count(*) as count FROM test WHERE text LIKE '%something%
: 16.028197050095s.SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%')
0,87045907974243.SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%' LIMIT 1)
: 0.044898986816406с.Но теперь, с полем BIGINT PK, только одна запись равна '321321':
SELECT * FROM test2 WHERE id ='321321' LIMIT 1
сmysql_num_rows()
: 0,0089840888977051с.SELECT count(*) as count FROM test2 WHERE id ='321321'
: 0.00033879280090332s.SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321')
: 0.00023889541625977s.SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321' LIMIT 1)
: 0.00020313262939453s. (БЫСТРЕЕ)источник
SELECT 1 FROM test WHERE texte LIKE '%something%' LIMIT 1
select 1 ... limit 1
, бесполезно окружать избранным существуетSELECT 1 FROM test WHERE ...
, безSELECT EXISTS
него. Предположительно, так волосы быстрее.Краткий пример ответа @ ChrisThompson
Пример:
Используя псевдоним:
источник
В своих исследованиях я могу найти результат, набирающий скорость.
источник
Я чувствую, что стоит отметить, хотя в комментариях было затронуто, что в этой ситуации:
Превосходит:
Это связано с тем, что первый запрос может быть удовлетворен индексом, тогда как второй требует поиска строки (если, возможно, все столбцы таблицы не включены в используемый индекс).
Добавление
LIMIT
пункта позволяет двигателю остановиться после нахождения любого ряда.Первый запрос должен быть сопоставим с:
Который посылает те же сигналы в движок (1 / * здесь не имеет значения), но я все равно написал бы 1, чтобы усилить привычку при использовании
EXISTS
:Возможно, имеет смысл добавить
EXISTS
перенос, если вам требуется явный возврат, если ни одна строка не совпадает.источник
Рекомендуем вам не использовать,
Count
потому что count всегда создает дополнительные нагрузки для использования базы данныхSELECT 1
и возвращает 1, если ваша запись тут же, в противном случае возвращается null, и вы можете справиться с этим.источник
COUNT запрос быстрее, хотя , возможно , не заметно, но по мере получения желаемого результата, как должно быть достаточно.
источник
Иногда очень удобно получить первичный ключ с автоинкрементом (
id
) строки, если он существует, а0
если нет.Вот как это можно сделать в одном запросе:
источник
IFNULL(id, 0)
здесь вместоCOUNT(*)
?Для таблиц не-InnoDB вы также можете использовать таблицы информационной схемы:
http://dev.mysql.com/doc/refman/5.1/en/tables-table.html
источник
Я бы пошел с
COUNT(1)
. Это быстрее , чемCOUNT(*)
потому , чтоCOUNT(*)
тесты , чтобы увидеть , если хотя бы один столбец в этой строке! = NULL. Вам это не нужно, особенно потому, что у вас уже есть условие (WHERE
пункт).COUNT(1)
вместо этого проверяет достоверность1
, которая всегда действительна и требует гораздо меньше времени для проверки.источник
Или вы можете вставить необработанную часть SQL в условия, чтобы у меня было «условие» => массив («Member.id NOT IN (SELECT Membership.member_id FROM memberships AS Membership)»)
источник
COUNT(*)
оптимизированы в MySQL, поэтому первый запрос, скорее всего, будет быстрее, вообще говоря.источник