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  /  ...  /  Controlling Query Plan Evaluation

10.9.1 查询计划评估控制

查询优化器的任务是找到执行 SQL 查询的最优计划。因为“好”和“坏”计划之间的性能差异可能是数量级的(即秒级别与小时或天级别),因此大多数查询优化器,包括 MySQL 的优化器,都会对所有可能的查询评估计划进行近乎穷举的搜索。对于连接查询,MySQL 优化器调查的可能计划数量随着查询中引用的表数量的增加而呈指数增长。当表数量较少(通常少于 7 到 10 个)时,这不是问题。但是,当提交较大查询时,查询优化所花费的时间可能会成为服务器性能的主要瓶颈。

一种更灵活的查询优化方法允许用户控制优化器在搜索最优查询评估计划时的穷举程度。一般来说,优化器调查的计划越少,编译查询所花费的时间越少。另一方面,因为优化器跳过了一些计划,它可能会错过找到最优计划。

可以使用两个系统变量来控制优化器对计划数量的评估行为:

  • 变量 optimizer_prune_level 告诉优化器根据每个表访问的行数估算来跳过某些计划。我们的经验表明,这种“有根据的猜测”很少错过最优计划,并且可能大幅减少查询编译时间。这就是为什么这个选项默认启用(optimizer_prune_level=1)。然而,如果您认为优化器错过了更好的查询计划,这个选项可以被关闭(optimizer_prune_level=0),但风险是查询编译可能需要更长时间。注意,即使使用这个启发式方法,优化器仍然会探索大致指数级别的计划数量。

  • optimizer_search_depth 变量告诉优化器在每个不完整计划的“未来”中应该看多远,以评估是否应该进一步扩展它。较小的 optimizer_search_depth 值可能会导致查询编译时间减少几个数量级。例如,具有 12、13 或更多表的查询如果 optimizer_search_depth 接近查询中的表数,可能需要数小时甚至数天来编译。同时,如果编译时 optimizer_search_depth 等于 3 或 4,对于同一查询,优化器可能在不到一分钟内编译。如果您不确定 optimizer_search_depth 的合理值是什么,该变量可以设置为 0,以便让优化器自动确定值。