# 优化器可能选择错误的执行计划

<mark style="color:orange;">**有很多种原因会导致 MySQL 优化器选择错误的执行计划**</mark>，如下所示：

* <mark style="color:blue;">**统计信息不准确**</mark>

  MySQL 服务器依赖**存储引擎**提供的统计信息来评估成本，但是**有的存储引擎提供的信息是准确的，有的偏差可能非常大。**

  例如，InnoDB 因为其 MVCC 的架构，并不能维护一个数据表的行数的精确统计信息。
* <mark style="color:blue;">**成本指标并不完全等同于运行查询的实际成本**</mark>

  **即使统计数据是准确的，实际的查询成本也可能超过或者低于 MySQL 估算的近似值。**

  例如，有时候某个执行计划虽然需要读取更多的页面，但是它的成本却更低。因为如果这些页面都是顺序读或者这些页面都已经在内存中的话，那么它的访问成本将很低。**MySQL 并不知道哪些页面在内存中、哪些在磁盘中，所以查询在实际执行过程中到底需要多少次物理 I/O 是无法得知的**。
* <mark style="color:blue;">**MySQL 的最优可能和你想的最优不一样**</mark>

  你可能希望执行时间尽可能短，但是 MySQL 只是基于其成本模型选择最优的执行计划，而有些时候这并不是最快的执行方式。所以，这里我们看到的根据执行成本来选择执行计划并不是完美的模型。
* MySQL 从<mark style="color:blue;">**不考虑其他并发执行的查询**</mark>，这可能会影响到当前查询的速度
* <mark style="color:blue;">**MySQL 并不是任何时候都是基于成本的优化，它有时也会基于一些固定的规则**</mark>

  例如，如果存在全文搜索的 **MATCH()** 子句，则在存在  FULLTEXT 索引的时候就使用全文索引。即使有时候使用其他索引和 WHERE 条件可以远比这种方式要快，MySQL 也仍然会使用对应的全文索引。
* <mark style="color:blue;">**MySQL 不会考虑不受其控制的操作的成本**</mark>

  例如，执行**存储函数**或者**用户自定义函数**的成本。
* 优化器<mark style="color:blue;">**有时候无法估算所有可能的执行计划，所以它可能错过实际上最优的执行计划**</mark>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bohans.gitbook.io/ji-chu/mysql/ji-chu-zhi-shi/mysql-cha-xun-de-zhi-xing-guo-cheng/mysql-cha-xun-you-hua-qi/you-hua-qi-ke-neng-xuan-ze-cuo-wu-de-zhi-xing-ji-hua.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
