Подтвердить что ты не робот

Является ли COUNT (*) в SQL Server постоянной операцией времени? Если нет, почему бы и нет?

Я читал эту дискуссию в еще одном сообщении, где этот вопрос поднимал кто-то другой. Прежде чем читать дискуссию, я всегда думал, что SQL Server (и другие СУБД) сохраняют глобальное количество строк для каждой таблицы где-то в метаданных, но обсуждение, похоже, говорит, что это не так. Зачем? Count(*) (без какой-либо фильтрации), являющийся такой общей операцией, получит огромный импульс, если это O (1). Даже не рассматривая Count(*), общее количество строк в таблице является такой важной частью информации. Почему они не замечают это?

Кроме того, зачем нам "загружать" целые строки (как указано в сообщении, который я связал), чтобы их подсчитать? Должны ли индексы или ПК и т.д. Быть достаточными для их подсчета?

4b9b3361

Ответ 1

Нет, COUNT(*) не является операцией с постоянным временем. A COUNT(*) должен возвращать количество строк, которые соответствуют текущему предикату сканирования (т.е. Предложение WHERE), так что только это сделало бы возврат свойства метаданных недействительным. Но даже если у вас нет предикатов, COUNT все еще должен удовлетворять текущей семантике изоляции транзакции, т.е. верните количество видимых строк (например, зафиксировано). Поэтому COUNT должен, и будет, в SQL Server, проверять и подсчитывать строки. Некоторые системы позволяют вернуть более быструю оценку".

Кроме того, в качестве побочного комментария, полагаясь на rows в sys.partitions, ненадежна. В конце концов, если этот счет будет гарантирован точным, нам не понадобится DBCC UPDATEUSAGE(...) WITH COUNT_ROWS. Существует несколько сценариев, которые исторически могут привести к тому, что этот счетчик будет дрейфовать отдельно от реальности (в основном, минимально зарегистрированные вложенные откаты), все, что я знаю, исправлено, но все еще оставляет проблемы с 1) обновленными таблицами из более ранних версий с ошибками и 2 ) другие, еще не обнаруженные, ошибки.

Кроме того, зачем нам "загружать" целые строки (как указано в сообщении, который я связал), чтобы их подсчитать? Должны ли индексы или ПК и т.д. Быть достаточными для их подсчета?

Это не 100% истинно. Существует не менее двух сценариев, которые не "загружают целые строки":

  • Узкие индексы rowstore загружают только строку 'index', которая может быть намного меньше
  • данные столбцов хранят только соответствующие сегменты столбца.

И большинство из того, что я говорю выше, не относятся к таблицам Hekaton.

Ответ 2

почему нам нужно "загружать" целые строки

Мы этого не делаем. SQL Server будет стремиться использовать наименьший индекс, который он может использовать, который может удовлетворить запрос.

Count(*) (без какой-либо фильтрации), являющейся такой общей операцией

Я думаю, вы переоцениваете его распространенность. Я не могу вспомнить последний раз, когда я беспокоился об общем количестве строк в одной таблице по сравнению с более фильтрованным представлением или счетчиком в более сложной объединенной операции.

Это была бы исключительно узкая оптимизация, которая могла бы принести пользу только одному типу запроса, и, как я уже сказал, я думаю, вы переоценили, как часто это происходит.