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

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

Это:

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

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

SELECT 1 FROM ... WHERE ...

// and then count the results with a built-in function, e.g. in PHP mysql_num_rows()

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

Ответ 1

Когда вы 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. Вы должны действительно обратить внимание на то, как используются индексы, когда есть много строк (десятки, миллионы и выше).

Ответ 2

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

show table status like '<TABLE NAME>' \G

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

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

$ mysqlshow --status <DATABASE> <TABLE NAME>

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

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

SELECT TABLE_NAME AS 'Table Name', TABLE_ROWS AS 'Rows' FROM information_schema.TABLES WHERE TABLES.TABLE_SCHEMA = ' имя_базы_данного ' AND TABLES.TABLE_TYPE = 'BASE TABLE';

Пример:

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

Ответ 6

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

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

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

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

Ответ 7

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

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

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

ПОСМОТРЕТЬ ГРАФ: эталонный график

Мой совет - использовать: SELECT COUNT(*) FROM table

Ответ 8

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

Ответ 9

Попробуйте следующее:

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

Ответ 10

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

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

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

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

Ответ 11

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

Ответ 12

Оператор count (*) с условием where в первичном ключе вернул счетчик строк намного быстрее, чтобы я избегал полного сканирования таблицы.

SELECT COUNT(*) FROM ... WHERE <PRIMARY_KEY> IS NOT NULL;

Это было намного быстрее для меня, чем

SELECT COUNT(*) FROM ...