データベースパフォーマンスの主な要因は、データベースで使用されるストレージエンジン、より具体的にはそのテーブルです。異なるストレージエンジンは、ある状況で別の状況よりも優れたパフォーマンスを提供します。一般的な使用については、考慮すべき2つの候補があります。これらは、デフォルトのMySQLストレージエンジンであるMyISAM、または高性能データベースを対象としたMySQLに組み込まれている代替エンジンであるInnoDBです。 2つのストレージエンジンの違いを理解する前に、「ロック」という用語を理解する必要があります。
MySQLのロックとは何ですか?
データベース内に保存されているデータの整合性を保護するために、MySQLはロックを採用しています。ロックとは、簡単に言えば、データがアクセスされないように保護することを意味します。ロックが適用されている場合、ロックを開始したクエリ以外ではデータを変更できません。ロックは、保存された情報の正確性を確保するために必要なコンポーネントです。各ストレージエンジンには、使用されるロックの異なる方法があります。データとクエリの方法によっては、1つのエンジンが別のエンジンよりも優れている場合があります。このシリーズでは、2つのストレージエンジンで採用されている最も一般的な2つのタイプのロックについて説明します。
テーブルのロック: テーブル内の1つ以上のセルを更新または削除する必要がある場合に、テーブル全体をロックする手法。テーブルロックは、デフォルトのストレージエンジンであるMyISAMで採用されているデフォルトの方法です。
例:MyISAMテーブルのロック | 列A | 列B | 列C | |
クエリ1の更新 | 行1 | 書き込み | データ | データ |
クエリ2SELECT(待機) | 行2 | データ | データ | データ |
クエリ3の更新(待機) | 行3 | データ | データ | データ |
クエリ4SELECT(待機) | 行4 | データ | データ | データ |
クエリ5SELECT(待機) | 行5 | データ | データ | データ |
この例は、1回の書き込み操作でテーブル全体がロックされ、他のクエリがUPDATEクエリの終了を待機する方法を示しています。 |
行レベルのロック: 範囲内の1つ以上のセルが変更または削除されている間に、テーブル内の有効な範囲の行をロックする動作。行レベルのロックは、InnoDBストレージエンジンで使用される方法であり、高性能データベースを対象としています。
例:InnoDB行レベルのロック | 列A | 列A | 列A | |
クエリ1の更新 | 行1 | 書き込み | データ | データ |
クエリ2SELECT | 行2 | 読書 | データ | データ |
クエリ3の更新 | 行3 | データ | 書き込み | データ |
クエリ4SELECT | 行4 | 読書 | 読書 | 読書 |
クエリ5SELECT | 行5 | 読書 | データ | 読書 |
この例は、行レベルのロックを使用して、テーブル全体ではなく更新中の行のみをロックすることにより、個々の行で複数のクエリを実行できるようにする方法を示しています。 |
MyISAMとInnoDB
2つのストレージエンジンを比較することで、MyISAMよりもInnoDBを使用することの間の議論の核心に到達します。頻繁に使用されるテーブルを持つアプリケーションまたはWebサイトは、テーブルロックのボトルネックを解決することにより、InnoDBストレージエンジンを使用して非常にうまく機能します。ただし、どちらもすべての状況で完全ではないため、一方を他方の上に使用するという問題は主観的なものです。両方のストレージエンジンには長所と制限があります。テーブルに最適なストレージエンジンを選択するには、データベースの構造とクエリの方法に関する深い知識が不可欠です。
MyISAMは、書き込みアクティビティよりもはるかに多くの読み取りアクティビティを必要とする大きなテーブルでInnoDBよりも優れたパフォーマンスを発揮します。 MyISAMの読みやすさは、テーブル全体をロックする方が、テーブルでロックされている行を特定するよりも速いため、InnoDBよりも優れています。表内の情報が多いほど、InnoDBがアクセスできない情報を特定するのにかかる時間が長くなります。アプリケーションがデータを頻繁に変更しない巨大なテーブルに依存している場合、MyISAMはInnoDBよりも優れたパフォーマンスを発揮します。逆に、テーブル内のデータが頻繁に変更される場合、InnoDBはMyISAMよりも優れています。テーブルの変更により、1秒あたりのデータの読み取りよりも書き込みデータが多くなります。このような状況では、InnoDBは、テーブル全体をロックするよりも簡単に大量のリクエストに対応できます。
InnoDBをWordPress、Magento、またはJoomlaサイトで使用する必要がありますか?
ほとんどの場合、ここでの簡単な答えは「はい」です。ホスティングサポートチームでLiquidWebの最も役立つ人間は、クライアントが今日のいくつかの標準的なWebアプリケーションを使用しているときに、いくつかのテーブルロックのボトルネックに遭遇しました。 WordPress、Magento、Joomlaなどの人気のあるサードパーティアプリケーションのほとんどのユーザーは、ストレージエンジンに関する情報に基づいた決定を行うために必要な、基盤となるデータベースコンポーネントまたはコードに関する知識が限られています。これらのコンテンツ管理システム(CMS)のほとんどのテーブルロックのボトルネックは、通常、サイトのすべてのテーブルをデフォルトのMyISAMではなくInnoDBに変更することで解決されます。サーバーでこれらのタイプのCMSの多くをホストしている場合は、MySQLのデフォルトのストレージエンジンを変更して、すべての新しいテーブルにInnoDBを使用し、新しいテーブルのインストールがInnoDBで開始されるようにすると便利です。
デフォルトのストレージエンジンの設定
default_storage_engine =InnoDB を追加して、デフォルトのストレージエンジンをInnoDBに設定します [mysqld]へ /etc/my.cnfにあるシステム設定ファイルのセクション。サーバーがファイルへの変更を検出するには、MySQLサービスを再起動する必要があります。
~ $ cat /etc/my.cnf
[mysqld]
log-error=/var/lib/mysql/mysql.err
innodb_file_per_table=1
default-storage-engine=innodb
innodb_buffer_pool_size=128M
MyISAMとInnoDBの間ですべてのテーブルを変換する
残念ながら、MySQLには本質的にテーブルを変換するオプションがなく、各テーブルを個別に変更する必要があります。 Liquid Webのサポートチームは、このプロセスのわかりやすいメンテナンス計画をまとめました。シェルアクセス(SSH)を介して必要なサーバーで実行できるスクリプトは、ストレージエンジン間ですべてのテーブルを変換します。
注ダウンタイムが発生した場合に備えて、この種のバッチ操作を実行する場合は、それに応じて計画してください。ベストプラクティスは、この規模の変更を実装する前にすべてのMySQLデータベースをバックアップすることです。これにより、データの損失を防ぐための簡単なリカバリポイントが提供されます。ステップ1: プレップ
ダウンタイムによる影響が最小限になる時間帯に開始するように計画します。このプロセス自体にはダウンタイムは必要ありませんが、予期しない状況から回復するためにダウンタイムが必要になる場合があります。
ステップ2: すべてのデータベースをファイルにバックアップ
次のコマンドは、 all-databases-backup.sqldという名前のすべてのデータベースの単一ファイルバックアップを作成し、変換が成功して明らかな問題がなくなったら削除できます。
mysqldump --all-databases > all-databases-backup.sql
ステップ3: 既存のテーブルエンジンをファイルに記録する
次のスクリプトを実行して、既存のテーブルエンジンを table-engine-backup.sqlという名前のファイルに記録します。 。その後、このファイルを後で「インポート」または「実行」して、必要に応じて元のエンジンに戻すことができます。
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=",Engine,";") FROM information_schema.tables WHERE table_schema NOT IN("mysql","information_schema","performance_schema");' | tee table-engine-backup.sql
何らかの理由でテーブルエンジンを元に戻す必要がある場合は、次を実行します。
mysql < table-engine-backup.sql
ステップ4a: MyISAMテーブルをInnoDBに変換する
以下のコマンドは、テーブルに障害が発生した場合でも続行され、変換に失敗したテーブルを通知します。出力はconvert-to-innodb.logという名前のファイルに保存されます 後で確認するためにw。
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=InnoDB;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "MyISAM";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-innodb.log
ステップ4b:すべてのInnoDBテーブルをMyISAMに変換する
このコマンドは、テーブルに障害が発生した場合でも続行され、変換に失敗したテーブルを通知します。出力は、 convert-to-myisam.logという名前のファイルにも保存されます。 後で確認するため。
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=MyISAM;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "InnoDB";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-myisam.log
MyISAMとInnoDBの間で単一のテーブルを変換する
次のコマンドは、単一のテーブルの変換がどのように実行されるかを示しています。
注database_nameを適切なデータベース名に置き換え、table_nameを正しいテーブル名に置き換えます。続行する前に、問題のテーブルの有効なバックアップがあることを確認してください。
単一のテーブルをファイルにバックアップする
mysqldump database_name table_name > backup-table_name.sql
単一のテーブルをInnoDBに変換する
mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=InnoDB;’
単一のテーブルをMyISAMに変換する:
mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=MyISAM;’
このシリーズの他の記事「MySQLパフォーマンス:長いクエリの識別」を確認して、データベース内の遅いクエリを特定してください。キャッシングと最適化について説明する次の記事にご期待ください。