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()
можно было бы подумать, что первый метод должен быть быстрее, так как это явно территория базы данных, и компонент database engine должен быть быстрее, чем кто-либо другой, при определении таких вещей внутри.
11 ответов
когда вы COUNT(*)
Он принимает индексы столбцов count, поэтому это будет лучший результат. Mysql с MyISAM двигатель на самом деле хранит количество строк, это не doensn считать все строки каждый раз, когда вы попытаетесь сосчитать все строки. (на основе столбца первичного ключа)
использование PHP для подсчета строк не очень умно, потому что вам нужно отправить данные из mysql в php. Зачем это делать, когда вы можете достичь того же на стороне mysql?
если COUNT(*)
медленно, вы должны выполнить EXPLAIN
по запросу и проверьте, действительно ли используются индексы и где они должны быть добавлены.
пример быстрый путь, но есть случай, где COUNT(*)
не подходит - когда вы начинаете группировать результаты, вы можете столкнуться с проблемой, где COUNT
на самом деле не считает все строки.
решение SQL_CALC_FOUND_ROWS
. Это обычно используется при выборе строк, но все равно необходимо знать общее количество строк (например, для пейджинговый.)
Когда вы выбираете строки данных, просто добавьте SQL_CALC_FOUND_ROWS
ключевое слово после выбора:
SELECT SQL_CALC_FOUND_ROWS [needed fields or *] FROM table LIMIT 20 OFFSET 0;
после выбора нужных строк, вы можете получить счет с этим один запрос:
SELECT FOUND_ROWS();
FOUND_ROWS()
должен быть вызван сразу после запроса выбора данных.
в заключение, все на самом деле сводится к тому, сколько записей у вас есть и что находится в инструкции WHERE. Вы действительно должны обратить внимание на то, как используются индексы, когда есть много строк (десятки тысяч, миллионы, и вверх).
после разговора с моими товарищами по команде Рикардо сказал нам, что более быстрый способ:
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
Отличный вопрос, отличные ответы. Вот быстрый способ повторить результаты, если кто-то читает эту страницу и пропускает эту часть:
$counter = mysql_query("SELECT COUNT(*) AS id FROM table");
$num = mysql_fetch_array($counter);
$count = $num["id"];
echo("$count");
этот запрос (который похож на то, что опубликовал bayuah) показывает хорошую сводку всех таблиц count внутри базы данных: (упрощенная версия хранимая процедура Ивана Качикатари который я очень рекомендую).
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(*)
vs 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 миллионами записей.
и нам нужно было знать много раз общее количество строк.
поэтому мы, программисты базы данных, решили, что в каждой таблице всегда есть запись, в которой хранятся общие номера записей. Мы обновили это число, в зависимости от вставки или удаления строк.
мы попробовали все другие способы. Это самый быстрый способ.