• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 控制查询计划评估

    查询优化器的任务是找到执行SQL查询的最佳计划。因为“好”和“坏”之间的性能差异计划可能是几个数量级(即几秒钟相对于几小时甚至几天),大多数查询优化器(包括MySQL的优化器)在所有可能的查询评估计划中或多或少地穷举搜索最佳计划。对于联接查询,MySQL优化器调查的可能计划的数量与查询中引用的表的数量成指数增长。对于少量表(通常少于7到10),这不是问题。但是,提交较大的查询时,花在查询优化上的时间可能很容易成为服务器性能的主要瓶颈。

    一种更灵活的查询优化方法,使用户可以控制优化器在搜索最佳查询评估计划时的详尽程度。通常的想法是,优化器调查的计划越少,则编译查询所花费的时间就越少。另一方面,由于优化器跳过了一些计划,因此可能会找不到最佳计划。

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

    • optimizer_prune_level变量告诉优化器根据对每个表访问的行数的估计来跳过某些计划。我们的经验表明,这种“有根据的猜测”很少会错过最佳计划,并且可能会大大减少查询的编译时间。这就是为什么此选项optimizer_prune_level=1默认为()的原因。但是,如果您认为优化器错过了更好的查询计划,则可以关闭此选项(optimizer_prune_level=0),可能会导致查询编译花费更长的时间。请注意,即使使用这种启发式方法,优化器仍会探索大约指数级的计划。
    • optimizer_search_depth变量告诉优化器应该考虑每个不完整计划的“未来”有多远,以评估是否应进一步扩展它。较小的值optimizer_search_depth可能会导致查询编译时间缩短几个数量级。例如,如果optimizer_search_depth查询的表数接近于12个,13个或更多,则很容易需要几个小时甚至几天来进行编译。同时,如果用optimizer_search_depth等于3或4,对于同一查询,优化器可以在不到一分钟的时间内完成编译。如果不确定什么是合理的值optimizer_search_depth,可以将该变量设置为0,以告知优化器自动确定该值。