#### 15.8.10.3 估计 InnoDB 表的分析表复杂性

[`分析表`](analyze-table.html)复杂性`InnoDB`表取决于：

-   采样的页数，定义为[`innodb_stats_persistent_sample_pages`](innodb-parameters.html#sysvar_innodb_stats_persistent_sample_pages).

-   表中的索引列数

-   分区数。如果表没有分区，则认为分区数为 1。

    使用这些参数，估计的近似公式[`分析表`](analyze-table.html)复杂性将是：

    的价值[`innodb_stats_persistent_sample_pages`](innodb-parameters.html#sysvar_innodb_stats_persistent_sample_pages) \*表中的索引列数\*分区数

    通常，结果值越大，执行时间越长[`分析表`](analyze-table.html).

笔记

[`innodb_stats_persistent_sample_pages`](innodb-parameters.html#sysvar_innodb_stats_persistent_sample_pages)定义在全局级别采样的页数。要设置为单个表采样的页数，请使用`STATS_SAMPLE_PAGES`选项[`创建表`](create-table.html)要么[`更改表`](alter-table.html).有关详细信息，请参阅[第 15.8.10.1 节，“配置持久优化器统计参数”](innodb-persistent-stats.html).

如果[`innodb_stats_persistent=OFF`](innodb-parameters.html#sysvar_innodb_stats_persistent)，采样的页数定义为[`innodb_stats_transient_sample_pages`](innodb-parameters.html#sysvar_innodb_stats_transient_sample_pages).看[第 15.8.10.2 节，“配置非持久优化器统计参数”](innodb-statistics-estimation.html)了解更多信息。

更深入的估计方法`分析表`复杂性，请考虑以下示例。

在[大 O 符号](http://en.wikipedia.org/wiki/Big_O_notation),[`分析表`](analyze-table.html)复杂性描述为：

```
 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`](innodb-parameters.html#sysvar_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`是分区数。如果未定义分区，则该表被视为单个分区。

    现在，考虑下表（表`吨`)，它有一个主键（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)
);
```

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

笔记

有关`InnoDB`持久统计表，请参阅[第 15.8.10.1 节，“配置持久优化器统计参数”](innodb-persistent-stats.html)

```
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 (`c`和`d`)

-   `n_cols_in_non_uniq_i`，所有非唯一索引中所有列的总数为 4 (`e`, `f`, `g`和`h`)

-   `n_cols_in_pk`, 主键的列数为 2 (`一种`和`b`)

-   `n_non_uniq_i`, 表中非唯一索引的数量为 2 (`i2nonuniq`和`i3nonuniq`))

-   `n_part`，分区数，为 1。

    您现在可以计算`innodb_stats_persistent_sample_pages` \*(2 + 4 + 2\*(1 + 2))\*1 来确定扫描的叶页数。和`innodb_stats_persistent_sample_pages`设置为默认值`20`，并且默认页面大小为 16`千字节`([`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size)=16384)，然后您可以估计 20\*12\*16384`字节`读表`吨`, 或约 4`MiB`.

笔记

全部 4`MiB`可能不会从磁盘读取，因为某些叶子页面可能已经缓存在缓冲池中。
