去年,我们将数据从旧产品环境迁移到新产品的新环境中。
由于新产品仍然新鲜,我们发现一些新的查询在迁移之后非常缓慢。我们通过在查询联接子句中添加'FORCE INDEX(SOME_INDEX)‘来修正其中的几个。这立即解决了我们的问题,大大加快了查询速度。
最近,我们再次看到新产品的性能下降,去年我们使用“强制索引(SOME_INDEX)”优化的查询在没有强制索引部分的情况下不会更快(基本上使用去年的原始查询现在更快)
办公室里有人说,mysql保存自己的索引统计数据,而mysql服务器继续工作时,它在创建查询流方面变得更加高效。(这意味着最初它的统计数据较少,这就是为什么暗示强制索引对它有帮助,在使用了一年之后,它自己的统计数据就足够了)。
这是正确的吗?对此还有其他合理的解释吗?
发布于 2020-08-25 23:21:51
在没有任何索引提示的情况下,优化器使用统计信息来决定使用哪个索引。它以合理(但不总是)明智的方式更新统计数据。
如果有提示,比如FORCE INDEX,它会忽略统计信息,并在可能的情况下使用给定的索引。
也许FORCE一开始是有益的。但是后来,由于新的行、值的分布变化或月亮的相位,表中的数据发生了变化。现在这个指数不再是最优的了。
你的经验是为什么我警告人们不要使用提示,说:“这可能有帮助,但明天伤害。”
如果您想讨论特定的查询,请提供SHOW CREATE TABLE和EXPLAIN SELECT... --这可能是一个不同的复合查询,如果没有提示,将比您所拥有的更好。
更多关于历史的..。优化器在5.6,5.7和8.0中进行了大量的工作。一个巨大的变化正在转向“基于成本的”模式。从理论上讲,它产生了更好的效果。在实践中,它很少改变任何东西。而且,就像你的案例所显示的那样,它有时会让人心痛。假设基于成本的模型通常比以前的算法更好。
当发生上述任何情况时,都会更新统计数据:
ANALYZE TABLE。在少数情况下,这是一个错误的索引选择的“修复”,但它可能坚持,也可能不坚持。ALTER。https://dba.stackexchange.com/questions/274324
复制相似问题