文档主页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  InnoDB 和 MyISAM 索引统计收集

10.3.8 InnoDB 和 MyISAM 索引统计收集

存储引擎会收集有关表的统计信息,供优化器使用。表统计信息基于值组,其中值组是具有相同键前缀值的一组行。对于优化器而言,一个重要的统计信息是平均值组大小。

MySQL 在以下方面使用平均值组大小

  • 估计每个 ref 访问需要读取多少行

  • 估计部分连接生成多少行,即以下形式的操作生成的行的数量:

    (...) JOIN tbl_name ON tbl_name.key = expr

随着索引的平均值组大小增加,索引对于这两个目的的用处会降低,因为每次查找的平均行数会增加:为了使索引在优化方面有效,最好是每个索引值都针对表中的少量行。当给定索引值产生大量行时,索引的用处会降低,MySQL 就不太可能使用它。

平均值组大小与表基数相关,表基数是指值组的数量。SHOW INDEX 语句会显示一个基于 N/S 的基数值,其中 N 是表中的行数,S 是平均值组大小。该比率会得出表中值组的大致数量。

对于基于 <=> 比较运算符的连接,NULL 的处理方式与任何其他值相同:NULL <=> NULL,就像 N <=> N 对于任何其他 N 一样。

但是,对于基于 = 运算符的连接,NULL 与非 NULL 值不同:expr1 = expr2expr1expr2(或两者)为 NULL 时不成立。这会影响以下形式的比较的 ref 访问:tbl_name.key = expr:当 expr 的当前值为 NULL 时,MySQL 不会访问该表,因为比较不可能成立。

对于 = 比较,表中存在多少个 NULL 值并不重要。对于优化而言,相关的值是非 NULL 值组的平均大小。但是,MySQL 目前没有启用收集或使用该平均大小的功能。

对于 InnoDBMyISAM 表,您可以通过 innodb_stats_methodmyisam_stats_method 系统变量分别对表统计信息的收集进行一定程度的控制。这些变量具有三个可能的取值,它们的不同之处如下:

  • 当变量设置为 nulls_equal 时,所有 NULL 值都被视为相同(即,它们都形成一个值组)。

    如果 NULL 值组的大小远大于平均非 NULL 值组的大小,这种方法会使平均值组大小向上倾斜。这会使索引在优化器看来,对于寻找非 NULL 值的连接而言,比实际用处更低。因此,nulls_equal 方法可能会导致优化器在应该使用索引时,没有将索引用于 ref 访问。

  • 当变量设置为 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方法。