Database JUNKY

MySQL,MariaDBを中心としたブログです

MySQL8 インビジブルインデックス(INVISIBLE INDEX)の勧め

その索引使われていますか?

MySQLで長年運用しているうちに、パフォーマンスチューニングが必要になって、ほとんどが、チューニング効果の高い、索引チューニング(インデックスチューニング)をしていきますよね。そんでインデックスをぺたぺた張っているうちに、インデクスだらけになり、気付いた時には、テーブルの全カラムに対して索引が設定されてたなんてことないですか?(自分だけかも)

その索引、本当に使われてますか? 使われていない索引が大量に存在すると、データの更新パフォーマンスが低下します。的確な答えではないのでですが、インデックスはある意味、インデックスのデータを含めたテーブルが一個できるといった認識をもってくれれば、使った数だけ、テーブルが増えていくって感覚をもってくれればイメージがつきやすいかな?って思います。

ということで、MySQL8.0で実装された、インビジブルインデックス(INVISIBLE INDEX)の活用方法について書いていきたいと思います。

インビジブルインデックス(INVISIBLE INDEX)

INVISIBLE=不可視って意味なんですが、ようは、物理的には存在するのですが、MySQLSQLパーサー)からは、見えない設定に変更することができるものです。MySQL8.0で実装されました。実際、この機能がない時って、本番の運用で試しに削除してみて、あら、サイトのパフォーマンスが低下して、再度インデックスを設定するという手間を省くことができるすぐれものなんです!

設定は簡単、これだけです!!

ALTER TABLE テーブル名 ALTER INDEX インデックス名 INVISIBLE;

これで、対象のインデックスを不可視にすることが可能になります

 。。とその前に

では、使われていないインデックスはどうっやって調べるの?という、そもそもの部分ですが、ものすごく参考になるサイトがありましたので、引用させてもらいます!

sawara.me

結果のみまとめると

SELECT
    OBJECT_SCHEMA,
    OBJECT_NAME,
    INDEX_NAME
FROM
    performance_schema.table_io_waits_summary_by_index_usage
WHERE
    OBJECT_SCHEMA LIKE '%schema_name%'
    AND INDEX_NAME IS NOT NULL
    AND INDEX_NAME NOT LIKE 'PRIMARY'
    AND COUNT_READ = 0;

SQLを発行するだけで、索引が使われていない、プライマリーキー以外のインデックス名を洗い出すことが可能になるって感じですね。MySQL8.0がクエリーキャッシュは廃止されているので、単純にそのまま、上記SQLを発行することですみそうです。

まとめ

前後、逆になってしまいましたが、スムーズな不要索引の落とし方の順番は

  1. 使われていないインデックスを調べる
  2. 上記対象のインデクスを、INVISIBLEにする
  3. 影響がないのが確認できたら、DROP INDEX を発行する
  4. 影響があった場合、INVISIBLEをVISIBLEに戻す

ALTER TABLE テーブル名 ALTER INDEX インデックス名 VISIBLE;

といった手順です。

この作業を繰り返すことにより不要なインデックスの削除がスムーズに進むと思います!!

f:id:hit10231023:20180309104332j:plain

hit.hateblo.jp