mysql_upgrade 到 5.7 后,优化器不在大 IN 子句上使用索引

Ste*_*enE 5 mysql migration upgrade mysql-5.6 mysql-5.7

我有一个与其他人描述的类似的问题。

  • 在MySQL 5.6.23-72.1-log中,子句中包含大量值的查询IN使用索引,需要10分钟才能运行;
  • 在5.7.19-17中,相同的查询不使用索引,并且需要至少2(有时超过4)小时

我试过了

  • set session eq_range_index_dive_limit=4294967295; 没有运气。
  • set @@global.max_seeks_for_key=100; 还是没有运气。

这是在我升级了一些服务器之后发生的。

mysql_upgrade 没有报告任何问题。

正如我所指出的,我看到了其他问题,但其中提出的答案都没有解决我的问题。


非常感谢罗兰多到目前为止的回答。我继续在 my.cnf 的 [mysqld] 部分对此进行了测试

optimizer_switch = index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=off,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=off,derived_merge=off
Run Code Online (Sandbox Code Playgroud)

遗憾的是,索引仍然没有被拾取。我尝试关闭所有新添加的选项:

duplicateweedout=off
condition_fanout_filter=off
derived_merge=off
Run Code Online (Sandbox Code Playgroud)

我什至尝试过,因为我在我的解释计划中SET optimizer_switch='block_nested_loop=off' 得到了'Using where; Using join buffer (Block Nested Loop)'和。'Using temporary; Using filesort'

还在挠头。谢谢,最重要的是升级导致很多查询不使用索引,这仍然是一个痛苦。数据库接近 2TB,但查询在 5.6 上的最后几个 master 中运行良好

Rol*_*DBA 5

你可能没有意识到这一点,MySQL 优化器在不同版本之间有不同的设置

对于 MySQL 5.6,optimizer_switch如下所示:

mysql> SELECT @@optimizer_switch\G
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,
                    index_merge_sort_union=on,
                    index_merge_intersection=on,
                    engine_condition_pushdown=on,
                    index_condition_pushdown=on,
                    mrr=on,mrr_cost_based=on,
                    block_nested_loop=on,batched_key_access=off,
                    materialization=on,semijoin=on,loosescan=on,
                    firstmatch=on,
                    subquery_materialization_cost_based=on,
                    use_index_extensions=on
Run Code Online (Sandbox Code Playgroud)

对于 MySQL 5.7,optimizer_switch如下所示:

mysql> SELECT @@optimizer_switch\G
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,
                    index_merge_sort_union=on,
                    index_merge_intersection=on,
                    engine_condition_pushdown=on,
                    index_condition_pushdown=on,
                    mrr=on,mrr_cost_based=on,
                    block_nested_loop=on,batched_key_access=off,
                    materialization=on,semijoin=on,loosescan=on,
                    firstmatch=on,duplicateweedout=on,
                    subquery_materialization_cost_based=on,
                    use_index_extensions=on,
                    condition_fanout_filter=on,derived_merge=on
Run Code Online (Sandbox Code Playgroud)

您可以为MySQL 5.6设置默认的optimizer_switch my.cnf,然后重新启动MySQL 5.7。然后,优化器的行为将与升级之前相同。对于新选项,设置duplicateweedout=offderived_merge=off

这不是一个完整的答案。你必须对此进行测试。