Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

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

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

对于 = 比较,不管表中有多少 NULL 值,对优化器目的来说,相关的值是非 NULL 值组的平均大小。然而,MySQL 目前不允许收集或使用该平均大小。

对于 InnoDBMyISAM 表,您可以通过 innodb_stats_methodmyisam_stats_method 系统变量控制表统计信息的收集。这些变量有三个可能的值,区别如下:

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

    如果 NULL 值组大小远远高于平均非 NULL 值组大小,这种方法会使平均值组大小上升。这使索引对优化器目的变得不那么有用,导致优化器不使用索引进行 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 方法。