MySQL: самый быстрый способ подсчета количества строк

Какой способ подсчета числа строк должен быть быстрее в MySQL?

Эта:

SELECT COUNT(*) FROM ... WHERE ... 

Или, альтернатива:

 SELECT 1 FROM ... WHERE ... // and then count the results with a built-in function, eg in PHP mysql_num_rows() 

Можно было бы подумать, что первый метод должен быть быстрее, так как это явно firebase database, а механизм базы данных должен быть быстрее, чем кто-либо другой при определении таких вещей, как это внутренне.

Когда вы COUNT(*) он принимает индексы столбцов count, поэтому это будет лучший результат. Mysql с механизмом MyISAM фактически хранит подсчет строк, он не подсчитывает все строки каждый раз, когда вы пытаетесь подсчитать все строки. (на основе столбца первичного ключа)

Использование PHP для подсчета строк не очень умно, потому что вы должны отправлять данные с mysql на php. Зачем это делать, когда вы можете добиться того же самого на стороне mysql?

Если COUNT(*) работает медленно, вы должны запустить EXPLAIN в запросе и проверить, действительно ли индексы используются, и где они должны быть добавлены.


Ниже приведен не самый быстрый способ, но есть случай, когда COUNT(*) не подходит – когда вы начинаете группировать результаты, вы можете столкнуться с проблемой, когда COUNT самом деле не подсчитывает все строки.

Решение – SQL_CALC_FOUND_ROWS . Обычно это используется, когда вы выбираете строки, но все же должны знать общее количество строк (например, для подкачки). Когда вы выбираете строки данных, просто добавьте ключевое слово SQL_CALC_FOUND_ROWS после SELECT:

 SELECT SQL_CALC_FOUND_ROWS [needed fields or *] FROM table LIMIT 20 OFFSET 0; 

После того, как вы выбрали нужные строки, вы можете получить счет с помощью этого единственного запроса:

 SELECT FOUND_ROWS(); 

FOUND_ROWS() необходимо вызывать сразу после запроса выбора данных.


В заключение, все фактически сводится к тому, сколько записей у вас есть и что есть в инструкции WHERE. Вы должны действительно обратить внимание на то, как используются индексы, когда есть много строк (десятки, миллионы и выше).

Поговорив с моими товарищами по команде, Рикардо сказал нам, что более быстрый способ:

 show table status like '' \G

Но вы должны помнить, что результат может быть не точным.

Вы также можете использовать его из командной строки:

 $ mysqlshow --status  

Дополнительная информация: http://dev.mysql.com/doc/refman/5.7/en/show-table-status.html

И вы можете найти полное обсуждение в mysqlperformanceblog

Отличный вопрос, отличные ответы. Вот быстрый способ повторить результаты, если кто-то читает эту страницу и пропускает эту часть:

 $counter = mysql_query("SELECT COUNT(*) AS id FROM table"); $num = mysql_fetch_array($counter); $count = $num["id"]; echo("$count"); 

Я всегда понимал, что приведенное ниже даст мне самые быстрые ответы.

 SELECT COUNT(1) FROM ... WHERE ... 

Этот запрос (который похож на то, что выложили байюа) показывает хорошее резюме всех таблиц, подсчитываемых внутри базы данных: (упрощенная версия хранимой процедуры Ivan Cachicatari, которую я очень рекомендую).

SELECT TABLE_NAME AS 'Table Name', TABLE_ROWS AS 'Rows' FROM information_schema.TABLES WHERE TABLES.TABLE_SCHEMA = ' YOURDBNAME ' AND TABLES.TABLE_TYPE = 'BASE TABLE' ;

Пример:

+-----------------+---------+ | Table Name | Rows | +-----------------+---------+ | some_table | 10278 | | other_table | 995 |

Если вам нужно получить подсчет всего набора результатов, вы можете воспользоваться следующим подходом:

 SELECT SQL_CALC_FOUND_ROWS * FROM table_name LIMIT 5; SELECT FOUND_ROWS(); 

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

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

Я сделал несколько тестов, чтобы сравнить время выполнения COUNT(*) и COUNT(id) (id – первичный ключ индексированной таблицы).

Количество испытаний: 10 * 1000 запросов

Результаты: COUNT(*) быстрее 7%

ПРОСМОТРЕТЬ ГРАФ: benchmarkgraph

Мой совет заключается в использовании: SELECT COUNT(*) FROM table

Возможно, вам захочется рассмотреть возможность выполнения SELECT max(Id) - min(Id) + 1 . Это будет работать, только если ваши идентификаторы являются последовательными, а строки не удаляются. Это очень быстро.

Попробуй это:

 SELECT table_rows "Rows Count" FROM information_schema.tables WHERE table_name="Table_Name" AND table_schema="Database_Name"; 

Я обработал столы для правительства Германии, иногда 60 миллионов записей.

И нам нужно было много раз знать полные строки.

Поэтому мы, программисты базы данных, решили, что в каждой таблице записывается одна запись, в которой хранятся общие номера записей. Мы обновили это число, в зависимости от строк INSERT или DELETE.

Мы пробовали все другие способы. Это, безусловно, самый быстрый способ.

EXPLAIN SELECT id FROM .... сделал трюк для меня. и я мог видеть количество строк в столбце rows результата.

  • Отсутствие повышения производительности после использования openMP в программе оптимизируется для последовательного запуска
  • Делать или не делать: хранить изображения в базе данных
  • Зачем использовать AJAX, когда доступны WebSockets?
  • Какова (скрытая) стоимость ленивого значения Scala?
  • Инструменты для измерения затрат на связь MPI
  • Java: двумерный массив хранится в порядке столбцов или строк?
  • Производительность dynamic_cast?
  • Есть ли гарантия выравнивания возврата адреса с помощью новой операции C ++?
  • Производительность mgo-запросов кажется медленно медленной (500-650 мс)
  • Анатомия «утечки памяти»
  • MATLAB parfor медленнее, чем для - что не так?
  • Interesting Posts

    Воспроизвести фильм с Windows Media на DLNA TV: «не удалось получить информацию о медиа с медиа-сервера»

    Java 8: Разница между ссылкой метода Bound Receiver и UnBound Receiver

    Регулярное выражение, разделите строку заглавной буквой, но игнорируйте TLA

    C # DllImport с булевой функцией C ++ не возвращается правильно

    ngFor с индексом как значение в атрибуте

    Отключить ключ отключения на моей клавиатуре?

    Как передать пользовательский тип таблицы как хранимый параметр в C #

    Является ли мой лицензионный ключ для Windows 7 x86 действительным для установки x64 в Windows?

    Как отредактировать или добавить в Notepad ++ HTML / CSS автозаполнение?

    Gedit мигает и автоматически выходит при открытии файла

    Программно свернуть группу в ExpandableListView

    Вызов функции переопределения базового classа из метода базового classа

    Лучший способ конвертировать поле строки в метку времени в Spark

    Резервное копирование DHCP и фильтрация MAC-адресов. Являются ли они одинаковой ценностью?

    Express.js Ошибка маршрутизации: не удается установить заголовки после их отправки

    Давайте будем гением компьютера.