目的
MySQLのストレージエンジンは最近はInnoDBがデフォルトになっています。InnoDBはそれ以前のデフォルトであったMyISAMに比べ、
- トランザクションに対応している
- 行ロックが使用できる
というメリットがあります。特に後者ですが、MyISAMの場合は特定行への更新もテーブルロックになってしまうため、Webアプリケーションのような複数のクライアントが同時に同じテーブルに更新をかけるようなケースでは、パフォーマンスの低下を招いてしまいます。
さて、手元の環境でMySQLを使ったアプリの性能測定をしていたところ、多重アクセス時に顕著にパフォーマンスの低下が見られました。調査したところ、テーブルのストレージエンジンがなぜかMyISAMになっていました。
結論から言いますと、私は性能測定アプリをSpring Boot + Spring Data JPAで開発し、テスト用のテーブルをspring.jpa.hibernate.ddl-auto=create
で自動生成していました。このとき、相手がMySQLだと自動的にMyISAMを指定してテーブルが作成されていました。
本来はこのようなDDLの実行はアプリでやるのではなく、リリースやデプロイの仕組みの中でやるべきですので、恐らくHibernateのMySQL Dialectを作った人は、自動生成は簡易なテスト用途なので、管理が楽なMyISAMを使用する、という判断をしたのかもしれません。
しかし、テーブル定義が確定しない状態で試行錯誤しながら性能測定をしたいという特殊な事情もあったりするので、、、今回はAutoの場合でもInnoDBを使用する方法をメモします。
検証環境
- Spring Boot 2.0.1
- MySQL 8
手順
以下のシステムプロパティをセットします。application.propertiesではなくシステムプロパティである必要があります。
hibernate.dialect.storage_engine=innodb
Spring Bootの場合は実行時に-Dオプションで渡すのが楽でしょう。
java -Dhibernate.dialect.storage_engine=innodb -jar app.jar
簡単でしたね。