Sql: Как правильно проверить, существует ли запись - PullRequest
176 голосов
/ 23 ноября 2010

Чтение некоторой SQL Tuning документации. Я нашел это:

Select count(*):
- Подсчет количества строк
- Часто неправильно используется для проверки существованиязапись

действительно ли Select count(*) так плоха?

Как правильно проверить существование записи?

Ответы [ 8 ]

214 голосов
/ 23 ноября 2010

Лучше использовать одно из следующих:

-- Method 1.
SELECT 1
FROM table_name
WHERE key = value;

-- Method 2.
SELECT COUNT(1)
FROM table_name
WHERE key = value;

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

Сколько лет используемой вами документации? Несмотря на то, что вы прочитали хороший совет, большинство оптимизаторов запросов в недавних СУБД все равно оптимизируют SELECT COUNT(*), поэтому, хотя есть разница в теории (и в старых базах данных), вы не должны заметить никакой разницы на практике.

174 голосов
/ 23 ноября 2010

Я бы предпочел вообще не использовать функцию Count:

IF [NOT] EXISTS ( SELECT 1 FROM MyTable WHERE ... )
     <do smth>

Например, если вы хотите проверить, существует ли пользователь, прежде чем вставить его в базу данных, запрос может выглядеть следующим образом:

IF NOT EXISTS ( SELECT 1 FROM Users WHERE FirstName = 'John' AND LastName = 'Smith' )
BEGIN
    INSERT INTO Users (FirstName, LastName) VALUES ('John', 'Smith')
END
19 голосов
/ 23 ноября 2010

Вы можете использовать:

SELECT 1 FROM MyTable WHERE <MyCondition>

Если нет записи, соответствующей условию, результирующий набор записей пуст.

12 голосов
/ 23 ноября 2010

Другие ответы довольно хороши, но было бы также полезно добавить LIMIT 1 (или эквивалент , чтобы предотвратить проверку ненужных строк.

9 голосов
/ 23 ноября 2010

Вы можете использовать:

SELECT COUNT(1) FROM MyTable WHERE ... 

или

WHERE [NOT] EXISTS 
( SELECT 1 FROM MyTable WHERE ... )

Это будет более эффективно, чем SELECT *, поскольку вы просто выбираете значение 1 для каждой строки, а невсе поля.

Существует также небольшая разница между COUNT (*) и COUNT (имя столбца):

  • COUNT(*) будет считать все строки, включая нули
  • COUNT(column name) будет считать только ненулевые вхождения имени столбца
8 голосов
/ 08 апреля 2013
SELECT COUNT(1) FROM MyTable WHERE ...

будет проходить через все записи.Это причина, по которой его нельзя использовать для существования записи.

Я бы использовал

SELECT TOP 1 * FROM MyTable WHERE ...

После нахождения 1 записи он завершит цикл.

7 голосов
/ 14 января 2015

Вы можете использовать:

SELECT 1 FROM MyTable WHERE... LIMIT 1

Используйте select 1 для предотвращения проверки ненужных полей.

Используйте LIMIT 1 для предотвращения проверки ненужных строк.

0 голосов
/ 23 мая 2018

Я использую этот способ:

IIF(EXISTS (SELECT TOP 1 1 
                FROM Users 
                WHERE FirstName = 'John'), 1, 0) AS DoesJohnExist
...