Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  Controlling Query Plan Evaluation

10.9.1 控制查询计划评估

查询优化器的任务是找到执行 SQL 查询的最优计划。由于“好”和“坏”的性能差异可以是数量级(即秒 versus 小时甚至天),大多数查询优化器,包括 MySQL 的优化器,会对所有可能的查询评估计划进行尽量的搜索。对于连接查询,MySQL 优化器根据查询中引用表的数量来计算可能的计划数,这个数字以指数形式增长。对于小于 7 到 10 个表的查询,这不是问题。但是,当提交更大的查询时,查询优化时间很容易成为服务器性能瓶颈。

控制查询优化的灵活方法使用户可以控制优化器在搜索最优计划时的尽量程度。总之,优化器评估的计划越少,它编译查询就花费越少。另一方面,因为优化器跳过了一些计划,它可能会错过找到最优计划。

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

  • "optimizer_prune_level" 变量告诉优化器根据每个表的行数估计来跳过某些计划。我们的经验表明,这种"educated guess很少错过最优计划,可能大幅减少查询编译时间。这就是为什么这个选项默认是开启的(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,让优化器自动确定。