MySQL 统计信息是数据库优化器生成查询执行计划的关键依据,记录了表和索引的基本特性,辅助优化器估算查询成本、选择最优执行路径。
分为表级、索引级和列级三类。
描述表基本属性,如行数(TABLE_ROWS)、平均行长度(AVG_ROW_LENGTH)、数据大小(DATA_LENGTH)、索引大小(INDEX_LENGTH)、空闲空间(DATA_FREE)。获取方式:
SELECT TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTH, INDEX_LENGTH, DATA_FREE
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'your_database' AND TABLE_NAME = 'your_table';
描述索引特性,包括基数(CARDINALITY)、索引选择性(CARDINALITY / TOTAL_ROWS)、索引类型(BTREE、FULLTEXT、HASH 等)。可通过 SHOW INDEX FROM your_table;
获取。
描述列的数据分布,如最小值和最大值、数据分布、空值计数(NULL_COUNT),通常隐含在优化器行为中。
优化器依据统计信息选择执行计划,如索引扫描、全表扫描、排序方式等。
根据行数和索引分布估算读取页面数量,选择最低成本路径。
估算表大小,确定 JOIN 顺序和算法,如嵌套循环、哈希连接。
默认自动维护,当表数据变化超 10% 触发,可通过 innodb_stats_auto_recalc
参数(默认 ON
)控制。
ANALYZE TABLE your_table;
:更新表统计信息。OPTIMIZE TABLE your_table;
:更新统计信息并整理表和索引。FLUSH TABLES;
:刷新表统计信息缓存。默认存储在内存,重启重新计算。启用 persistent_stats
可持久化到磁盘:
SET PERSIST innodb_stats_persistent = ON;
TABLES
表查 表级统计信息,STATISTICS
表查索引级统计信息。EXPLAIN SELECT * FROM your_table WHERE column = value;
:查询优化器执行计划。统计信息是估算的,表数据频繁变化时不精确。
高并发场景下,更新可能导致性能波动。
列数据分布不均时,优化器可能做出次优选择,可通过 ANALYZE
或 USE INDEX
优化。
用 ANALYZE TABLE
和 OPTIMIZE TABLE
更新,监控表变化,必要时重新生成。
启用 innodb_stats_persistent
减少重建开销。
通过 innodb_stats_sample_pages
参数控制采样页面数,默认 8,可提高精度:
SET GLOBAL innodb_stats_sample_pages = 32;
为常用查询添加高选择性索引。
SELECT CONCAT('ANALYZE TABLE `', TABLE_SCHEMA, '`.`', TABLE_NAME, '`;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE';
DELIMITER //
CREATE PROCEDURE UpdateAllStatistics()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE dbName VARCHAR(64);
DECLARE tblName VARCHAR(64);
DECLARE cur CURSOR FOR
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO dbName, tblName;
IF done THEN
LEAVE read_loop;
END IF;
SET @query = CONCAT('ANALYZE TABLE `', dbName, '`.`', tblName, '`');
PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur;
END;
//
DELIMITER ;
执行:CALL UpdateAllStatistics();
#!/bin/bash
USER="your_user"
PASSWORD="your_password"
HOST="localhost"
mysql -u$USER -p$PASSWORD -h$HOST -N -e "SELECT CONCAT('ANALYZE TABLE \`', TABLE_SCHEMA, '\`.\`', TABLE_NAME, '\`;') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE';" | mysql -u$USER -p$PASSWORD -h$HOST
MySQL 统计信息对优化查询性能至关重要。定期更新和优化可提升查询效率,掌握维护方法是数据库管理员和开发人员必备技能。
欢迎关注公众号《小周的数据库进阶之路》,更多精彩知识和干货尽在其中。