Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  InnoDB and MyISAM Index Statistics Collection

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 不是真的,当expr1expr2(或两个都)为NULL时。这影响了ref访问对于形式的比较:tbl_name.key = expr:MySQL 不会访问表,如果当前expr的值为NULL,因为比较不能是真的。

对于=比较,不管表中有多少个NULL值。为了优化目的,相关值是非NULL值组的平均大小。但是,MySQL 目前还不支持收集或使用该平均大小。

对于 InnoDBMyISAM 表,您可以通过设置 innodb_stats_methodmyisam_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表的统计信息,可以使用以下方法之一:

使用innodb_stats_methodmyisam_stats_method时需要注意以下几点:

  • 您可以强制收集表统计信息,正如前面所描述的那样。然而,MySQL也可能自动收集统计信息。例如,在执行对某个表的语句时,如果这些语句修改了该表,MySQL可能会收集统计信息。(这可能发生在批量插入或删除操作中,或者一些ALTER TABLE语句中,例如。)如果发生这种情况,统计信息将使用在该时刻的innodb_stats_methodmyisam_stats_method变量中指定的方法。因此,如果您使用一种方法收集统计信息,但是在后续自动收集表统计信息时系统变量设置为另一方法,那么将使用另一方法。

  • 没有办法知道用于生成给定表统计信息的方法是哪种。

  • 这些变量仅适用于InnoDBMyISAM表。其他存储引擎只有一个方法来收集表统计信息。通常,这个方法更接近于nulls_equal方法。