2011-06-29 2 views
13

Я бегу запрос, как это в MSSQL2008:"SELECT COUNT (column)" быстрее/медленнее, чем "SELECT COUNT (*)"?

select count(*) 
from t1 
inner join t2 on t1.id = t2.t1_id 
inner join t3 on t1.id = t3.t1_id 

Предположим t1.id имеет NOT NULL ограничение. Поскольку они являются внутренними соединениями, а t1.id никогда не может быть нулевым, использование count(t1.id) вместо count(*) должно привести к тому же конечному результату. Мой вопрос: будет ли производительность такой же?

Мне также интересно, могут ли объединения повлиять на это. Я понимаю, что добавление или удаление соединения повлияет как на производительность, так и на длину набора результатов. Предположим, что без изменения шаблона объединения вы устанавливаете count для таргетинга только на одну таблицу. Разве это имеет значение? Другими словами, существует ли разница между этими двумя запросами:

select count(*) from t1 inner join t2 on t1.id = t2.t1_id 
select count(t1.*) from t1 inner join t2 on t1.id = t2.t1_id 

COUNT(id) vs. COUNT(*) in MySQL отвечает на этот вопрос для MySQL, но я не мог найти ответы на MS-SQL конкретно, и я не могу найти вообще ничего, что учитывает фактор join.

ПРИМЕЧАНИЕ: Я попытался найти эту информацию как в Google, так и в SO, но было сложно разобраться, как сложить мой поиск.

+0

Возможные Дубликаты: http://stackoverflow.com/questions/1221559/count-vs-count1 http://stackoverflow.com/questions/2710621/count -vs-count1-vs-countpk-which-is-better –

ответ

-1

select count(*) будет медленнее, поскольку он пытается извлечь все. Указание столбца (PK или любой другой индексированный столбец) ускорит работу, поскольку механизм запроса заранее знает, что он ищет. Он также будет использовать индекс, а не идти против таблицы.

+0

Я думаю, что это было правдой давным-давно, но предыдущие дискуссии по этой теме показывают, что это уже не так. Двигатели базы данных достаточно умны, чтобы знать, что счетчик (*) должен проверять наличие строки и не будет получать все значения для строки. http://stackoverflow.com/questions/1221559/count-vs-count1 –

+0

@ Micheal: Я не думаю, что это универсально. Например, в прошлый раз, когда я проверял, DB2 на zOS v9 все еще извлекала все. Это было довольно давно. Если кто-то не знает точной работы БД, с которой он имеет дело, я думаю, что его можно избежать, если не считать count (*). – Mrchief

+0

Хорошо, я стою исправлено - это звучит разумно, что это не универсально ... но OP специфицировал SQL Server 2008. –

8

Я попробовал несколько SELECT COUNT(*) FROM MyTable vs. SELECT COUNT(SomeColumn) FROM MyTable с различными размерами столов, и где SomeColumn раз является кластеризация ключевой столбец, когда он находится в некластерном индекса, и как только это не в индексе вообще.

Во всех случаях, со всеми размерами столов (от 300'000 строк до 170 миллионов строк), я никогда не видел какая-то разница с точки зрения либо плана скорости, ни исполнения - во всех случаях, COUNT обрабатывается выполнение кластерного сканирования индекса -> то есть сканирование всей таблицы, в основном. Если есть некластеризованный индекс, то сканирование происходит по этому индексу - даже при выполнении SELECT COUNT(*)!

Кажется, что нет какой-либо разницы в скорости или приближении, как эти вещи подсчитываются - чтобы подсчитать их все, SQL Server просто нужно отсканировать весь период таблицы.

Испытания проводились на SQL Server 2008 R2 Developer Edition