Официальная документация MySQL 5.1 признает, что InnoDB не дает точной статистики с SHOW TABLE STATUS
. В то время как таблицы MYISAM специально хранят внутренний кеш метаданных, таких как количество строк и т. Д., Механизм InnoDB хранит как данные таблицы, так и индексы в * / var / lib / mysql / ibdata **
InnoDB не имеет подходящего индексного файла, позволяющего быстро запрашивать номера строк.
Несовместимые номера строк таблицы сообщаются SHOW TABLE STATUS
, потому что InnoDB динамически оценивает значение 'Rows', выбирая диапазон данных таблицы (в * / var / lib / mysql / ibdata **), а затем экстраполирует приблизительное число рядов. Настолько, что документация InnoDB признает неточность номера строки до 50% при использовании SHOW TABLE STATUS
В документации MySQL предлагается использовать кэш запросов MySQL для получения согласованных запросов номеров строк, но в документах не указано как . Краткое объяснение того, как это можно сделать, приведено ниже.
Сначала убедитесь, что кэширование запросов включено:
mysql> SHOW VARIABLES LIKE 'have_query_cache';
Если значение have_query_cache равно NO , включите кэш запросов, добавив следующие строки в / etc / my.cnf , а затем перезапустите mysqld.
have_query_cache=1 # added 2017 08 24 wh
query_cache_size = 1048576
query_cache_type = 1
query_cache_limit = 1048576
(подробнее см. http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)
Запрос содержимого кеша с помощью
mysql> SHOW STATUS LIKE 'Qcache%';
Теперь используйте оператор SQL_CALC_FOUND_ROWS
в запросе SELECT
:
SELECT SQL_CALC_FOUND_ROWS COUNT(*) FROM my_innodb_table
SQL_CALC_FOUND_ROWS
попытается выполнить чтение из кэша и, если этот запрос не будет найден, выполнить запрос к указанной таблице, а затем зафиксировать количество строк таблицы в кэше запросов. Дополнительные выполнения вышеупомянутого запроса (или других «кэшируемых» операторов SELECT
- см. Ниже) будут обращаться к кэшу и возвращать правильный результат.
Последующие 'cachable' SELECT
запросы - даже если они LIMIT
результат - будут обращаться к кешу запросов и позволят вам получить (только один раз) общее количество строк таблицы с помощью
SELECT FOUND_ROWS();
, который возвращает правильный итог строки таблицы предыдущего кэшированного запроса.