Pull to refresh

Comments 13

Аааа, «рядки» сломали мой мозг, теперь меня отправят в больничку, где сестрички будут делать мне укольчики!
UFO just landed and posted this here
мой на SATUS-е сломался )

мне вот интересно почему он каждый раз показывает новое значение, хотя данные в таблице могут не меняться, странное у них приближенное вычисление…
Собственно это меня и интересует, причем разброс больше указанных 40-50%. Такое впечатление что берется поправка на силу и направление ветра на Марсе.
Насколько я знаю, в MyISAM таблицах есть специальное поле, где хранится число записей, поэтому в любой момент времени мы знаем, сколько там данных, не выполняя запрос. Кроме того, в MyISAM быстро отрабатывает запрос SELECT COUNT(*).
В InnoDb количество записей оценивается на основе реальных данных в таблице. А кол-во рядов (в том же phpmyadmin, например) это приблизительные данные. И не забывайте про транзакции.
Кстати, SELECT COUNT(*) там будет работать медленно, поэтому нужно ставить WHERE и желательно по индексированному полю.
Собственно, в мануале это всё есть.
InnoDB does not keep an internal count of rows in a table. (In practice, this would be somewhat complicated due to multi-versioning.) To process a SELECT COUNT(*) FROM t statement, InnoDB must scan an index of the table, which takes some time if the index is not entirely in the buffer pool. If your table does not change often, using the MySQL query cache is a good solution. To get a fast count, you have to use a counter table you create yourself and let your application update it according to the inserts and deletes it does. SHOW TABLE STATUS also can be used if an approximate row count is sufficient. See Section 13.2.13.1, “InnoDB Performance Tuning Tips”.
Главная причина: InnoDB — обработчик, поддерживающий транзакции. И в любой момент времени дя разных транзакций в таблице может быть разное количество строк.
Это понятно, но почему при каждом обновлении количество меняется, да и разброс просто безумно большой от -70% до +50% (это то что я видел).
Не думаю что трудно было реализовать обновление количества строк в таблице после каждой транзакции, если в ней были insert, replace, delete, truncate,… на конкретную таблицу, а хранить можно и в памяти, 8байт на каждую таблицу innodb совсем не накладно.
Ну транзацакции то тоже могут быть очень разные. Если транзакция будет с уровнем видимости READ UNCOMMITED, Вам придётся обновлять счётчик этой транзакции при любом измении таблицы. Т.е. если у Вас работает сотня паралелльных транзакций, каждая из них должна будет проверять всю сотню и менять в ней такие счётчики. Выйдет уже совсем сложно и запутанно.

К тому же запрос SELECT count(*) FROM table редко кому может понадобится выполнять часто. Обычно всегда есть условие WHERE. А с условием WHERE уж точно никакие счётчики не помогут.
Sign up to leave a comment.

Articles