Я работаю в команде SQL Server и, надеюсь, могу уточнить некоторые моменты в этой теме (я раньше этого не видел, поэтому мне жаль, что команда разработчиков не делала этого раньше).
Во-первых, семантической разницы между select count(1) from table
и select count(*) from table
нет. Они возвращают одинаковые результаты во всех случаях (и это ошибка, если нет). Как отмечено в других ответах, select count(column) from table
семантически отличается и не всегда возвращает те же результаты, что и count(*)
.
Во-вторых, в отношении производительности в SQL Server (и в SQL Azure) могут иметь значение два аспекта: работа во время компиляции и работа во время выполнения. Работа во время компиляции - это незначительный объем дополнительной работы в текущей реализации. В некоторых случаях расширение * распространяется на все столбцы, после чего выводится обратно до 1 столбца, выводимого из-за того, как некоторые из внутренних операций работают при связывании и оптимизации. Я сомневаюсь, что это проявится в любом измеримом тесте и, вероятно, затеряется в шуме всех других вещей, которые происходят под прикрытием (таких как автостатистика, сеансы xevent, накладные расходы хранилища запросов, триггеры и т. Д.). Это может быть несколько тысяч дополнительных инструкций процессора. Таким образом, count (1) выполняет чуть меньше работы во время компиляции (что обычно происходит один раз, и план кэшируется в нескольких последующих выполнениях). Что касается времени выполнения, при условии, что планы одинаковы, не должно быть никакой измеримой разницы. (Один из предыдущих примеров показывает разницу - скорее всего, из-за других факторов на машине, если план такой же).
Относительно того, как план может быть другим. Это крайне маловероятно, но это потенциально возможно в архитектуре текущего оптимизатора. Оптимизатор SQL Server работает как поисковая программа (представьте: компьютерная программа, играющая в шахматы, ищущая различные альтернативы для разных частей запроса и оценивающая альтернативы, чтобы найти самый дешевый план за разумное время). Этот поиск имеет несколько ограничений на то, как он работает, чтобы компиляция запросов заканчивалась в разумные сроки. Для запросов, выходящих за рамки тривиальных, существуют фазы поиска, и они имеют дело с траншами запросов, основанными на том, насколько дорогостоящим оптимизатор считает, что запрос потенциально может выполняться. Существует 3 основных этапа поиска, и каждый этап может использовать более агрессивную (дорогую) эвристику, пытаясь найти более дешевый план, чем любое предыдущее решение. В конце концов, в конце каждой фазы происходит процесс принятия решения, который пытается определить, должен ли он вернуть план, который он нашел до сих пор, или должен продолжать поиск. Этот процесс использует общее время, затраченное на данный момент, в сравнении с оценочной стоимостью лучшего плана, найденного до сих пор. Таким образом, на разных машинах с разными скоростями ЦП возможно (хотя и редко) получить разные планы из-за тайм-аута на более ранней стадии с планом по сравнению с переходом на следующую фазу поиска. Есть также несколько похожих сценариев, связанных с тайм-аутом последней фазы и, возможно, нехваткой памяти для очень и очень дорогих запросов, которые занимают всю память на машине (обычно это не проблема для 64-битных систем, но это была большая проблема назад на 32-битных серверах). В конечном итоге, если вы получите другой план, производительность во время выполнения будет отличаться. Я не думаю, что маловероятно, что разница во времени компиляции НИКОГДА приведет к возникновению любого из этих условий.
Net-net: Пожалуйста, используйте любой из двух вариантов, который вам нужен, поскольку в практической форме ничего из этого не имеет значения. (Честно говоря, существует гораздо более значительный фактор, влияющий на производительность в SQL).
Надеюсь, это поможет. Я написал главу книги о том, как работает оптимизатор, но я не знаю, уместно ли размещать его здесь (так как я все еще верю, что я получаю от него небольшие гонорары). Таким образом, вместо публикации я опубликую ссылку на выступление, которое я дал на SQLBits в Великобритании о том, как оптимизатор работает на высоком уровне, чтобы вы могли видеть различные основные фазы поиска более подробно, если хотите. чтобы узнать об этом. Вот ссылка на видео: https://sqlbits.com/Sessions/Event6/inside_the_sql_server_query_optimizer