我正在尝试确定MySQL优化器从何处获取可用于表的索引列表,当它估算(准备)查询的成本时。
ANALYZE TABLE
确定索引基数(如SHOW INDEX
输出的“基数”列中所示)索引树并相应地更新索引基数估计。由于这些只是估计,因此重复运行ANALYZE TABLE可能会产生不同的数字。这使得ANALYZE TABLE
在InnoDB表上速度很快,但由于没有考虑所有行,因此不能100%准确。
我正在尝试确定MySQL优化器从何处获取可用于表的索引列表,当它估算(准备)查询的成本时。
ANALYZE TABLE
确定索引基数(如SHOW INDEX
输出的“基数”列中所示)索引树并相应地更新索引基数估计。由于这些只是估计,因此重复运行ANALYZE TABLE可能会产生不同的数字。这使得ANALYZE TABLE
在InnoDB表上速度很快,但由于没有考虑所有行,因此不能100%准确。
Answers:
直接的答案是
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)
您可以使用以下命令从该表中进行选择
SELECT * FROM information_schema.statistics
WHERE table_schema='mydb' AND table_name='mytable';
或通过查看统计信息
请记住,此表在写繁重的环境中并不总是准确的。您必须定期对所有经常更新的MyISAM表运行ANALYZE TABLE。否则,在开发EXPLAIN查询计划时,依赖于information_schema.statistics的MySQL Query Optimizer有时会做出错误的选择。索引统计信息必须是最新的。
ANALYZE TABLE对InnoDB表完全没有影响。InnoDB的所有索引统计信息都是通过跳入BTREE页面来按需计算的。因此,当您对InnoDB表运行SHOW INDEXES FROM时,显示的基数始终是近似值。
更新2011-06-21 12:17 EDT
Re:ANALYZE TABLE对InnoDB表完全没有影响。
我不确定这个说法是否正确。我们已经大量读写innodb表,并且当mysql优化器做出错误选择时,查询的解释输出显示出错误的策略。Innodb表中的SHOW INDEXES也显示出它们的基数值变化很大。但是,在那些innodb表上运行ANALYZE命令可以修复解释计划,还可以消除基数的方差行为。我不知道Innodb表上的ANALYZE table命令是否一直有帮助,但是在我们的例子中,它确实有99%的时间有帮助。
通过在查询中包含“ STRAIGHT_JOIN”,我们完全消除了mysql优化器的错误选择。这迫使mysql优化器不要做出错误的选择或任何选择,而只是遵循我们在查询中定义的JOIN条件。
MyISAM的ANALYZE TABLE扫描整个表并重建统计信息,该统计信息保存在(我认为).MYI文件中。很少需要它。
InnoDB的ANALYZE TABLE 会做一些事情-它会进行上述提到的潜水。问题在于它可能会有所帮助,可能会使情况变得更糟,或者(很可能)不会产生任何明显的改变(除了基数外)。
较新的版本承诺允许将8种非随机探测器更改为(1)更多随机性,(2)让您更改“ 8”(这有其优点和缺点!),以及(3)在重新启动时保存。
底线:InnoDB仍然没有做到“正确”。在需要时进行分析,但不要屏住呼吸。
更新资料
重新措辞... ANALYZE TABLE
有一个临时的对InnoDB表的优化影响(可能有益,可能没有效果)。
“较新版本”:从5.6.6(2012)和MariaDB 10.1(2014)开始,统计数据得到了更好的处理,ANALYZE
现在(1)不需要的频率越来越多,(2)更具永久性。