ivo*_*ron 16 mysql index-statistics
我正在尝试确定 MySQL 优化器在估计(准备)查询的成本时从何处获取可用于表的索引列表。
对此的直接答案是
mysql> desc information_schema.statistics;
+---------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+-------+
| TABLE_CATALOG | varchar(512) | NO | | | |
| TABLE_SCHEMA | varchar(64) | NO | | | |
| TABLE_NAME | varchar(64) | NO | | | |
| NON_UNIQUE | bigint(1) | NO | | 0 | |
| INDEX_SCHEMA | varchar(64) | NO | | | |
| INDEX_NAME | varchar(64) | NO | | | |
| SEQ_IN_INDEX | bigint(2) | NO | | 0 | |
| COLUMN_NAME | varchar(64) | NO | | | |
| COLLATION | varchar(1) | YES | | NULL | |
| CARDINALITY | bigint(21) | YES | | NULL | |
| SUB_PART | bigint(3) | YES | | NULL | |
| PACKED | varchar(10) | YES | | NULL | |
| NULLABLE | varchar(3) | NO | | | |
| INDEX_TYPE | varchar(16) | NO | | | |
| COMMENT | varchar(16) | YES | | NULL | |
| INDEX_COMMENT | varchar(1024) | NO | | | |
+---------------+---------------+------+-----+---------+-------+
16 rows in set (0.01 sec)
Run Code Online (Sandbox Code Playgroud)
你可以从那个表中选择
SELECT * FROM information_schema.statistics
WHERE table_schema='mydb' AND table_name='mytable';
Run Code Online (Sandbox Code Playgroud)
或通过执行查看统计数据
请记住,此表在写入繁重的环境中并不总是准确的。您必须定期对所有频繁更新的 MyISAM 表运行ANALYZE TABLE。否则,依赖于 information_schema.statistics 的 MySQL 查询优化器有时会在为查询制定 EXPLAIN 计划时做出错误的选择。索引统计信息必须尽可能是最新的。
ANALYZE TABLE 对 InnoDB 表绝对没有影响。InnoDB 的所有索引统计信息都是通过深入 BTREE 页面按需计算的。因此,当您对 InnoDB 表运行 SHOW INDEXES FROM 时,显示的基数始终是近似值。
更新 2011-06-21 12:17 EDT
小智 6
Re:ANALYZE TABLE 对 InnoDB 表绝对没有影响。
我不确定这个说法是否属实。我们有大量的 innodb 表读写,当 mysql 优化器做出错误的选择时,查询的解释输出显示错误的策略。以及来自 Innodb 表的 SHOW INDEXES 显示它们的基数值有很大的差异。但是在这些 innodb 表上运行 ANALYZE 命令修复了解释计划并消除了基数的差异行为。我不知道 Innodb 表上的 ANALYZE table 命令是否一直有帮助,但在我们的例子中,它在大约 99% 的情况下确实有帮助。
通过在查询中包含“STRAIGHT_JOIN”,我们完全消除了 mysql 优化器的错误选择。这迫使 mysql 优化器不要做出错误的选择或任何选择,而只是遵循我们在查询中定义的 JOIN 条件。
| 归档时间: |
|
| 查看次数: |
10241 次 |
| 最近记录: |