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


MySQL 8.4 参考手册  /  ...  /  估计 InnoDB 表的 ANALYZE TABLE 复杂度

17.8.10.3 估计 InnoDB 表的 ANALYZE TABLE 复杂度

InnoDB 表的 ANALYZE TABLE 复杂度取决于

使用这些参数,估计 ANALYZE TABLE 复杂度的近似公式为

innodb_stats_persistent_sample_pages 的值 * 表中索引列的数量 * 分区数

通常,结果值越大,ANALYZE TABLE 的执行时间越长。

注意

innodb_stats_persistent_sample_pages 定义了全局级别采样的页面数。要设置单个表采样的页面数,请在 CREATE TABLEALTER TABLE 中使用 STATS_SAMPLE_PAGES 选项。有关更多信息,请参阅第 17.8.10.1 节,“配置持久化优化器统计信息参数”

如果 innodb_stats_persistent=OFF,则采样的页面数由 innodb_stats_transient_sample_pages 定义。有关更多信息,请参阅第 17.8.10.2 节,“配置非持久化优化器统计信息参数”

有关估计 ANALYZE TABLE 复杂度的更深入方法,请考虑以下示例。

大 O 表示法 中,ANALYZE TABLE 的复杂度描述为

 O(n_sample
  * (n_cols_in_uniq_i
     + n_cols_in_non_uniq_i
     + n_cols_in_pk * (1 + n_non_uniq_i))
  * n_part)

其中

  • n_sample 是采样的页面数(由 innodb_stats_persistent_sample_pages 定义)

  • n_cols_in_uniq_i 是所有唯一索引中所有列的总数(不包括主键列)

  • n_cols_in_non_uniq_i 是所有非唯一索引中所有列的总数

  • n_cols_in_pk 是主键中的列数(如果没有定义主键,InnoDB 会在内部创建一个单列主键)

  • n_non_uniq_i 是表中非唯一索引的数量

  • n_part 是分区数。如果没有定义分区,则该表被视为单个分区。

现在,考虑以下表(表 t),它有一个主键(2 列)、一个唯一索引(2 列)和两个非唯一索引(每个 2 列)

CREATE TABLE t (
  a INT,
  b INT,
  c INT,
  d INT,
  e INT,
  f INT,
  g INT,
  h INT,
  PRIMARY KEY (a, b),
  UNIQUE KEY i1uniq (c, d),
  KEY i2nonuniq (e, f),
  KEY i3nonuniq (g, h)
);

对于上述算法所需的列和索引数据,请查询表 tmysql.innodb_index_stats 持久索引统计信息表。n_diff_pfx% 统计信息显示了为每个索引统计的列。例如,主键索引统计了列 ab。对于非唯一索引,除了用户定义的列之外,还统计了主键列 (a,b)。

注意

有关 InnoDB 持久统计信息表的更多信息,请参阅第 17.8.10.1 节,“配置持久化优化器统计信息参数”

mysql> SELECT index_name, stat_name, stat_description
       FROM mysql.innodb_index_stats WHERE
       database_name='test' AND
       table_name='t' AND
       stat_name like 'n_diff_pfx%';
  +------------+--------------+------------------+
  | index_name | stat_name    | stat_description |
  +------------+--------------+------------------+
  | PRIMARY    | n_diff_pfx01 | a                |
  | PRIMARY    | n_diff_pfx02 | a,b              |
  | i1uniq     | n_diff_pfx01 | c                |
  | i1uniq     | n_diff_pfx02 | c,d              |
  | i2nonuniq  | n_diff_pfx01 | e                |
  | i2nonuniq  | n_diff_pfx02 | e,f              |
  | i2nonuniq  | n_diff_pfx03 | e,f,a            |
  | i2nonuniq  | n_diff_pfx04 | e,f,a,b          |
  | i3nonuniq  | n_diff_pfx01 | g                |
  | i3nonuniq  | n_diff_pfx02 | g,h              |
  | i3nonuniq  | n_diff_pfx03 | g,h,a            |
  | i3nonuniq  | n_diff_pfx04 | g,h,a,b          |
  +------------+--------------+------------------+

根据上面显示的索引统计数据和表定义,可以确定以下值

  • n_cols_in_uniq_i,所有唯一索引中所有列的总数(不包括主键列),为 2(cd

  • n_cols_in_non_uniq_i,所有非唯一索引中所有列的总数,为 4(efgh

  • n_cols_in_pk,主键中的列数,为 2(ab

  • n_non_uniq_i,表中非唯一索引的数量,为 2(i2nonuniqi3nonuniq))

  • n_part,分区数,为 1。

现在可以计算 innodb_stats_persistent_sample_pages * (2 + 4 + 2 * (1 + 2)) * 1 以确定扫描的叶页数。将 innodb_stats_persistent_sample_pages 设置为默认值 20,默认页面大小为 16 KiBinnodb_page_size=16384),则可以估计为表 t 读取了 20 * 12 * 16384 字节,约为 4 MiB

注意

可能不会从磁盘读取所有 4 MiB,因为某些叶页可能已缓存在缓冲池中。