2010-11-23 3 views
133

Чтение некоторых SQL Tuning документации я нашел это:Sql: Как правильно проверить, если запись существует

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

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

Каков правильный способ проверки наличия записи?

ответ

163

Лучше использовать

select 1 
from table 
where key = value; 

select count(1) 
from table 
where key = value; 

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

Сколько лет в документации, которую вы используете? Хотя вы хорошо читали советы, большинство оптимизаторов запросов в последних RDBMS оптимизируют select count(*) в любом случае, поэтому, хотя есть разница в теории (и более старых базах данных), вы не должны замечать никаких различий на практике.

6

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

SELECT COUNT(1) FROM MyTable WHERE ... 

или

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

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

Там также тонкое различие между COUNT (*) и COUNT (имя столбца):

  • COUNT(*) будет считать все строки, в том числе нулей
  • будет рассчитывать только ноны нуля вхождений имени столбца
+1

Вы ошибочно полагаете, что СУБД каким-то образом проверит все эти столбцы. Разница в производительности между `count (1)` и `count (*)` будет отличаться только от большинства СУБД с головным мозгом. – paxdiablo 2010-11-23 08:20:58

+0

** @ paxdiablo ** Вы предлагаете, чтобы полагаться на детали реализации - хорошая идея? – 2010-11-23 08:24:05

+2

Нет, я говорю, что _you_ на самом деле полагаются на детали реализации, заявляя, что это будет более эффективно. Если вы действительно хотите обеспечить максимальную производительность, вы должны профилировать ее для конкретной реализации с использованием репрезентативных данных или просто забыть об этом полностью. Все остальное потенциально вводит в заблуждение и может кардинально измениться при перемещении (например) с DB2 на MySQL. – paxdiablo 2010-11-23 08:30:29

12

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

SELECT 1 FROM MyTable WHERE <MyCondition> 

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

126

Я предпочел бы не использовать функцию 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 
12

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

6
SELECT COUNT(1) FROM MyTable WHERE ... 

будет проходить через все записи. Именно по этой причине это плохо для использования в качестве записи.

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

SELECT TOP 1 * FROM MyTable WHERE ... 

После обнаружения 1 запись, он прекращает цикл.

5

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

SELECT 1 FROM MyTable WHERE... LIMIT 1 

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

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

Смежные вопросы