web-dev-qa-db-ja.com

mysql_upgradeを5.7にした後、オプティマイザが大きなIN句でインデックスを使用しない

私が説明した他の何人かと同様の問題があります。

  • MySQL 5.6.23-72.1-logでは、IN句に多数の値を含むクエリはインデックスを使用し、実行に10分かかります。
  • 5.7.19-17では、同じクエリはインデックスを使用せず、少なくとも2(時には4を超える)hoursを使用します。

私はもう試した

  • _set session eq_range_index_dive_limit=4294967295_;運が悪い。
  • _set @@global.max_seeks_for_key=100_;まだ運がない。

これは、一部のサーバーをアップグレードした後に発生しました。

Mysql_upgradeは問題を報告していません。

既に述べたように、他の質問も見ましたが、提案された回答のどれも状況を解決していません。


これまでの回答について、Rolandoに感謝します。私は先に進み、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
_

残念ながら、インデックスはまだ取得されていません。新しく追加されたすべてのオプションをオフにしてみました:

_duplicateweedout=off
condition_fanout_filter=off
derived_merge=off
_

説明プランで'Using where; Using join buffer (Block Nested Loop)'と_SET optimizer_switch='block_nested_loop=off'_を取得していたので、_'Using temporary; Using filesort'_を試してみました。

まだ頭を掻いている。おかげで、最終的には、アップグレードによって多くのクエリでインデックスが使用されなくなったため、依然として問題が発生しています。データベースはほぼ2TBですが、5.6にある最後のいくつかのマスターでクエリは正常に実行されます

2
StephenE

あなたはこれに気づいていないかもしれませんが、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

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

MySQL 5.6のoptimizer_switchのデフォルトをmy.cnfに設定して、MySQL 5.7を再起動できます。その後、オプティマイザの動作はアップグレード前と同じになります。新しいオプションについては、duplicateweedout=offおよびderived_merge=offを設定します。

これは完全な答えではありません。これをテストする必要があります。

2
RolandoMySQLDBA