10.3.8 InnoDB和MyISAM索引统计信息收集
存储引擎收集表的统计信息,以供优化器使用。表统计信息基于值组,值组是具有相同键前缀值的一组行。对于优化器目的来说,一个重要的统计信息是平均值组大小。
MySQL 使用平均值组大小在以下方式:
-
估算每个
ref
访问所需读取的行数 -
估算部分连接产生的行数,即由操作
(...) JOIN tbl_name ON tbl_name.key = expr
当索引的平均值组大小增加时,该索引对于这两个目的来说变得不太有用,因为每个索引值目标的行数增加:为了使索引对优化器有用,它最好每个索引值都目标小于表中的行数。当给定的索引值产生了大量行时,该索引变得不太有用,MySQL也更不可能使用它。
平均值组大小与表卡drod性相关,这是指值组的数量。SHOW INDEX
语句显示基于N/S
的卡drod性值,其中N
是表中的行数和S
是平均值组大小。该比率yield一个approximate的值组数量在表中。
对于基于<=>比较运算符的连接,NULL
不会被特殊对待:NULL <=> NULL
,与任何其他值N
相同。
然而,对于基于=运算符的连接,NULL
与非NULL
值不同:
不是真的,当expr1
= expr2
expr1
或expr2
(或两个都)为NULL
时。这影响了ref
访问对于形式的比较:
:MySQL 不会访问表,如果当前tbl_name.key
= expr
expr
的值为NULL
,因为比较不能是真的。
对于=比较,不管表中有多少个NULL
值。为了优化目的,相关值是非NULL
值组的平均大小。但是,MySQL 目前还不支持收集或使用该平均大小。
对于 InnoDB
和 MyISAM
表,您可以通过设置 innodb_stats_method
和 myisam_stats_method
系统变量来控制表统计信息的收集。这些变量有三个可能的值,以下是它们的区别:
-
当变量设置为
nulls_equal
时,将对所有NULL
值进行处理(即它们都形成一个单一的值组)。如果
NULL
值组的大小远高于非NULL
值组的平均大小,这种方法会使得平均值组大小上升。这使得索引对优化器看起来不那么有用,特别是在执行 join 操作时寻找非NULL
值。因此,nulls_equal
方法可能会导致优化器在应该使用索引的情况下不使用索引。 -
当变量设置为
nulls_unequal
时,不会将NULL
值视为相同。相反,每个NULL
值都会形成一个大小为 1 的值组。如果您有许多
NULL
值,这种方法会使平均值组的大小下降。如果平均非NULL
值组的大小很大,那么将每个NULL
值计为1个组的大小,导致优化器对索引的估算过高,从而在查找非NULL
值的连接中使用该索引。因此,nulls_unequal
方法可能会导致优化器在其他方法下使用该索引进行ref
查找。 -
当变量设置为
nulls_ignored
时,NULL
值将被忽略。
如果您通常使用许多连接该用<=>
而不是=
,那么在比较中NULL
值不具特别性质,并且一个NULL
值等于另一个。在这种情况下,nulls_equal
是适当的统计方法。
系统变量innodb_stats_method
具有全局值;系统变量myisam_stats_method
具有全局和会话值。设置全局值将影响对应存储引擎的表统计信息。设置会话值将只影响当前客户端连接的统计信息。这意味着,您可以强制一个表的统计信息使用给定的方法,而不影响其他客户端,通过设置myisam_stats_method
会话值。
要重新生成MyISAM表的统计信息,可以使用以下方法之一:
-
将表更改为使其统计信息失效(例如,插入一行,然后删除它),然后设置
myisam_stats_method
并执行ANALYZE TABLE
语句
使用innodb_stats_method
和myisam_stats_method
时需要注意以下几点:
-
您可以强制收集表统计信息,正如前面所描述的那样。然而,MySQL也可能自动收集统计信息。例如,在执行对某个表的语句时,如果这些语句修改了该表,MySQL可能会收集统计信息。(这可能发生在批量插入或删除操作中,或者一些
ALTER TABLE
语句中,例如。)如果发生这种情况,统计信息将使用在该时刻的innodb_stats_method
或myisam_stats_method
变量中指定的方法。因此,如果您使用一种方法收集统计信息,但是在后续自动收集表统计信息时系统变量设置为另一方法,那么将使用另一方法。 -
没有办法知道用于生成给定表统计信息的方法是哪种。
-
这些变量仅适用于
InnoDB
和MyISAM
表。其他存储引擎只有一个方法来收集表统计信息。通常,这个方法更接近于nulls_equal
方法。