I know that you shouldn’t rely on the values returned by InnoDB’s SHOW TABLE STATUS.
In particular, the row count and avg data length.
But I thought maybe it was an accurate value taken at some point, and then innodb only refreshes it during an ANALYZE table or maybe some other infrequent event.
Instead what Im seeing is that I can run a SHOW TABLE STATUS on the same table 5 times in 5 seconds, and just get completely different numbers each time (despite the table not having any insert/delete activity in between)
Where are these values actually coming from? Are they just corrupt in innodb?
The official MySQL 5.1 documentation acknowledges that InnoDB does not give accurate statistics with
SHOW TABLE STATUS. Whereas MYISAM tables specifically keep an internal cache of meta-data such as number of rows etc, the InnoDB engine stores both table data and indexes in */var/lib/mysql/ibdata**InnoDB has no expedient index file allowing a quick query of row numbers.
Inconsistent table row numbers are reported by
SHOW TABLE STATUSbecause InnoDB dynamically estimates the ‘Rows’ value by sampling a range of the table data (in */var/lib/mysql/ibdata**) and then extrapolates the approximate number of rows. So much so that the InnoDB documentation acknowledges row number inaccuracy of up to 50% when usingSHOW TABLE STATUSMySQL documentation suggests using the MySQL query cache to get consistent row number queries, but the docs don’t specify how. A succinct explanation of how this can be done follows.
First, check that query caching is enabled:
If the value of have_query_cache is NO then enable the query cache by adding the following lines to /etc/my.cnf and then restart mysqld.
(for more information see http://dev.mysql.com/doc/refman/5.1/en/query-cache.html)
Query the contents of the cache with
Now use the
SQL_CALC_FOUND_ROWSstatement in aSELECTquery:SQL_CALC_FOUND_ROWSwill attempt a read from cache and, should this query not be found, execute the query against the specified table and then commit the number of table rows to the query cache. Additional executions of the above query (or other ‘cachable’SELECTstatements – see below) will consult the cache and return the correct result.Subsequent ‘cachable’
SELECTqueries – even if theyLIMITthe result – will consult the query cache and allow you to get (once-off only) the total table row numbers withwhich returns the previous cached query’s correct table row total.