Как стать автором
Обновить

Комментарии 46

как бы зависит от движка (InnoDB vs MyISAM).
имхо лучший выход — вешать триггеры на INSERT/DELETE и править метаданные таблицы.
Не совсем понятно зачем нужны триггеры?
в INSERT увеличиваем внутренний счетчик, в DELETE — уменьшаем.
потом просто выводим данные этого счетчика, когда нужно узнать количество записей.
А первый простейший вариант чем плох?
Первый вариант оптимизирован только для MyIsam таблиц, для InnoDB он также по индексу будет идти и считать.
Вы думаете разработчики БД не учли это и тупо не возращают количество записей в индексе?
в myisam количество строк хранится отдельно, в innodb надо посчитать сколько записей в индексе. с учетом того, что первичный индекс — кластерный, это может быть очень не быстрым делом.
А еще в случае наличия прав доступа на уровне строк, то нужно подсчитать число строк доступных данному пользователю…
Они это учли и не возращают тупо количество записей в индексе, т.к. это количество не всегда совпадает с количеством строк из-за транзакций и т.п.
одно дело взять данные из метадаты таблицы, которые _всегда_ в памяти, другое — обращаться к дереву индексов, и смотреть сколько там элементов.
первое — либо быстрее, либо так же по скорости.
А если DELETE не одной записи?
FOR EACH ROW
Обращаю внимание, что SHOW TABLE STATUS FROM database WHERE Name = 'table'; для InnoDB возвращает примерное значение.
НЛО прилетело и опубликовало эту надпись здесь
Угумц, но опрос тем и плох, что он не озвучивает цели этого па.

Для подавляющего большинства задач примерного значения будет достаточно, так что +1 вам и за тот вариант голосования :-)
SELECT COUNT(*) FROM table WHERE is_delete = 0
is_delete находится в индексе?
Нет, вьюшки подсчета всех записей отрабатываются помесячно\поквартально, поэтому скорость не критична.
НЛО прилетело и опубликовало эту надпись здесь
Заранее прошу прощения если вопрос покажется глупым, но в чем принципиальное различие между первым и вторым вариантом? Второй работает быстрее?
В большом количество советов в инете написано использовать LIMIT, так как это типа снижает нагрузку на БД. Вот народ и пихает везде, где может.
Единственно когда мне надо знать общее количество записей — это при использовании limit.
Догадайтесь с одного раза как это сделать в мискле.
Насколько я помню, SELECT COUNT(ID) FROM table; (или любое другое поле) быстрее, чем *
NULL значения не подсчитаются.
PK редко бывает NULL
Но, честно говоря, спасибо за коментарий. У меня был изначально этот вариант в списке, но я решил не плодить так много вариантов.
с чего бы это? count(*) — специальная форма записи для подсчета количества строк, а не значений
Всё с точностью до наоборот.
Давайте уточним — это обычно истинно для MS SQL Server т.к. по PK строится индекс.

В общем сценарии\ произвольной бд это может и не выполняться быстрее.
SELECT SQL_CALC_FOUND_ROWS… FROM дальше_обычный_запрос
Правда это не для всей таблицы, а для конкретного запроса.
Узнавать количество для всей таблицы как-то не было надобности.
То есть и вернуть все записи и построить пагинатор.
SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();


Принимается.

А как в PostgreSQL это сделать?
Чёрт, элитный браузер Хром 15.
Что примечательно — во втором случае иначе ссылки расставились ;)
Первый способ работает везде. Остальные от вариации поддержки стандарта и вендор специфик.
Небыло моего варианта! :)
select reltuples from pg_class where relname='table';
Дает не 100% результат, есть возможность что не будет хватать пару записей.
Не работает для view.
Та панятна, а дотошность свою приберегите для полезных дел :)
НЛО прилетело и опубликовало эту надпись здесь
Судя по комментариям, мир SQL ограничивается двумя видами таблиц MySQL :-)
А механика примерно одна и та же, алсо опрос неявно про мускл.
Вопрос заинтриговал:

SELECT COUNT(*) FROM `таблица`
starting 0.000007
checking query cache for query 0.000005
checking privileges on cached 0.000003
sending cached result to clien 0.000016
logging slow query 0.000002
cleaning up 0.000001

SELECT COUNT(*) FROM `таблица` LIMIT 1
starting 0.000007
checking query cache for query 0.000004
checking privileges on cached 0.000002
sending cached result to clien 0.000016
logging slow query 0.000002
cleaning up 0.000001

База 46,786,533 записей типа MyISAM объем 18.1 ГБ, при тестах нагрузка на сервер снята, т.е. оба результата сопоставимы. ИМХО большой разницы не увидел.
Так заинтриговал, что даже каменты выше не было времени почитать? В муисам общее количество строк в таблице хранится в метаданных, таблица может быть какого угодно размера — разницы не будет.
А мне вот еще интересно на основе каких теорий второй запрос может быть быстрее первого?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории