Я думаю, что когда автор сказал
however, in the real world, count() isn’t used very often
, они конкретно означали, что неквалифицированный count(*)
используется не очень часто, что является специфическим случаем, который оптимизирует MyISAM.
Мой собственный опыт подтверждает это - кроме некоторых сомнительных плагинов Munin, я не могу вспомнить, когда в последний раз я делал select count(*) from sometable
.
Например, где бы я ни делал пагинацию,обычно это результат какого-то поиска.Это подразумевает, что в любом случае будет предложение WHERE для ограничения результатов, поэтому я мог бы сделать что-то вроде select count(*) from sometable where conditions
, за которым следует select ... from sometable limit n offset m
.Ни один из которых не может использовать прямой ярлык «сколько строк в этой таблице».
Теперь верно, что если условия являются чисто индексными условиями, то некоторые базы данных могут объединить выходные данные покрывающих индексов вИзбегайте просмотра данных таблицы тоже.Что, безусловно, уменьшает количество блоков, на которые смотрят ... если это работает.Может случиться так, что, например, это только выигрыш, если запрос может быть удовлетворен одним индексом - зависит от реализации db.
Тем не менее, это далеко не всегда так - многонаши таблицы имеют флаг active
, который не индексируется, но часто фильтруется, поэтому в любом случае потребуется проверка в куче.
Если вам просто нужно знать, есть ли в таблице данные или нетPostgresql и многие другие системы сохраняют приблизительную статистику для каждой таблицы: вы можете проверить столбцы reltuples
и relpages
в каталоге, чтобы получить оценку того, сколько строк в таблице и сколько места в нейпринимает.Это хорошо, если ~ 6 значащих цифр достаточно точны для вас, и некоторое отставание в обновляемой статистике терпимо.В моем случае использования, который я помню (построение графика количества предметов в коллекции), это было бы хорошо для меня ...
Попытка поддерживать точный счетчик строк - это сложно.В статье, которую вы цитировали, кэшируется количество строк во вспомогательной таблице, что создает две проблемы:
- условие гонки между SELECT и INSERT, заполняющим вспомогательную таблицу (второстепенное, вы можете заполнить это административно)
- как только вы добавите строку в основную таблицу, у вас будет блокировка обновления строки во вспомогательной таблице.теперь любой другой процесс, пытающийся добавить в основную таблицу, должен ждать.
В результате параллельные транзакции сериализуются, а не могут выполняться параллельно, и вы потеряли writers-dontПреимущества MVCC в блоке - либо вы должны разумно ожидать, что сможете вставлять две независимые строки в одну и ту же таблицу одновременно.
MyISAM может кэшировать количество строк в таблице, так как оно используетсяна эксклюзивную блокировку на столе, когда кто-то пишет в него (iirc).InnoDB допускает более тонкую блокировку - но он не пытается кэшировать количество строк для таблицы.Конечно, если вас не волнует параллелизм и / или транзакции, вы можете воспользоваться ярлыками ... но тогда вы уходите от основного фокуса Postgresql, где целостность данных и транзакции ACID являются основными целями.
Я надеюсь, что это проливает некоторый свет.Должен признать, что я никогда не чувствовал необходимости в более быстром «подсчете (*)», поэтому в некоторой степени это просто завет «но это работает для меня», а не реальный ответ.