Альтернативы методам SQL COUNT (*)? - PullRequest
2 голосов
/ 21 февраля 2011

Я искал улучшения для проблемы PostgreSQL / InnoDB MVCC COUNT (*), когда нашел статью о реализации обхода в PostgreSQL . Однако автор сделал заявление, которое привлекло мое внимание:

Фанаты MySQL, как правило, указывают на Медленный подсчет PostgreSQL () как слабость, однако, в реальном мире, count () используется не очень часто, и если это действительно нужна, самая хорошая база данных системы обеспечивают основу для вас построить обходной путь.

Есть ли способы пропустить использование COUNT (*) при разработке ваших приложений?

Правда ли, что большинство приложений разработано так, что им это не нужно? Я использую COUNT() на большинстве своих страниц, так как все они нуждаются в нумерации страниц. О чем говорит этот парень? Поэтому некоторые сайты имеют только ссылку «следующий / предыдущий»?

Если перенести это в мир NoSQL, это тоже нужно делать, поскольку вы не можете очень легко записывать COUNT ()?

Ответы [ 2 ]

3 голосов
/ 22 февраля 2011

Я думаю, что когда автор сказал

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 являются основными целями.

Я надеюсь, что это проливает некоторый свет.Должен признать, что я никогда не чувствовал необходимости в более быстром «подсчете (*)», поэтому в некоторой степени это просто завет «но это работает для меня», а не реальный ответ.

0 голосов
/ 22 февраля 2011

В то время как вы спрашиваете больше о дизайне приложения, чем о вопросе с базой данных, есть больше подробностей о том, как подсчет выполняется в PostgreSQL, и альтернативах этому при Slow Counting .Если вам нужен быстрый подсчет чего-либо, вы можете вести его с помощью триггера, с примерами в ссылках.Это стоит вам немного на стороне вставки / обновления / удаления в обмен на ускорение этого.Вы должны знать заранее, что вы в конечном итоге захотите, чтобы счет сработал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...