パフォーマンスを得るためにいくつかの側面から MYSQL を最適化する方法を導入しました。 最適化は、最終的にはシステム全体を理解する必要があるため、複雑なタスクです。システムやアプリケーションに関する知識がほとんどなくても、部分的な最適化を行うことは可能ですが、システムをさらに最適化したい場合には、それを理解しておく必要があります。したがって、この章では、MySQL を最適化するためのさまざまな方法を説明し、いくつかの例を示します。ただし、システムをより高速に実行するための特定の (ますます困難になる) 方法が常に残っていることを覚えておいてください。もちろん、システムを高速化する最も重要な部分は基本設計です。また、システムが次のようなことを行うことを理解しておく必要があります。これが最も一般的なボトルネックです。
ディスクのシーク。1999 年に使用されていた最新のディスクの平均時間は通常 10 ミリ秒未満でした。したがって、理論的には、新しいディスクではこの時間は 1 秒あたり約 1000 回改善される可能性があります。 1 つのテーブルの最適化を最適化する方法は、データを読み取る必要がある適切な場所にあるディスクにデータを分散させることです。 1 つのディスク転送は 10 ~ 20Mb/s 程度です。これは、複数のディスクから並列 CPU サイクルで読み取ることができるため、最適化が容易になるはずです。データをメモリに読み込むとき (または、データがすでにそこにある場合)、それを実現するために処理する必要があります。この結果は、テーブルのメモリが比較的小さい場合に最も一般的な制限要因ですが、テーブルの速度が小さい場合、CPU が許容できる以上のデータを必要とする場合、メモリ帯域幅は通常問題になりません。 10.2 システム/コンパイル時間とブート パラメータのチューニング これらの決定の一部は非常に早い段階で行われるため、システム レベルのことから始めます。大きなゲインには重要ではないため、このセクションをざっと見るだけで十分な場合もありますが、このレベルでのゲインがどのくらい大きいかを把握しておくと、使用するデフォルトの OS が重要になります。ある程度複数の CPU を搭載している場合は、Solaris (スレッドが非常にうまく機能するため) または Linux (2.2 コアが非常に優れた SMP サポートを備えているため) を使用する必要があります。また、32 ビット マシンでは、Linux のファイル サイズ制限はデフォルトで 2G です。新しいファイル システム (XFS) がリリースされると、すぐにこの問題が修正されることを願っています。多くのプラットフォームで本番環境の MySQL を実行するわけではないため、プラットフォームを選択する前に、そのプラットフォームで実行することをテストすることをお勧めします。
その他の提案:
十分な RAM がある場合は、すべてのスワップ デバイスを削除できます。一部のオペレーティング システムでは、空きメモリがある場合でも、--skip -locking MySQL オプションを使用します。これは影響しません。 MySQL の機能は、1 つのサーバー上でのみ実行されている限り、myisamchk を実行する前にサーバーを停止する (または関連する部分をロックする) ことを忘れないでください。これは、すべての場合に外部ロックが利用できないためです。 MIT-pthreads でコンパイルする場合、flock() はすべてのプラットフォームの MIT-pthreads で完全にはサポートされていないため、--skip-locking オプションはデフォルトで on (on) になります。そうしないと、最初に mysqld サーバーをフラッシュまたはロックせずにテーブルに対して myisamchk を実行します。 --skip を使用している場合でも、LOCK TABLES/UNLOCK TABLES を使用できます。 -ロック。
コンパイルとリンクが MySQL の速度に与える影響
以下のテストのほとんどは Linux 上で MySQL ベンチマークを使用して実施されましたが、他のオペレーティング システムやワークロードについては、TCP の代わりに Unix ソケットを使用して接続すると最速の実行可能ファイルが得られることがわかります。 Linux では、pgcc と -O6 を使用して "sql_yacc.cc" をコンパイルすると、パフォーマンスが向上する可能性があります。gcc/pgcc は大量のメモリを必要とするため、約 200M のメモリが必要になります。すべての関数をインライン化するには、MySQL を構成するときに CXX=gcc を設定して、libstdc++ ライブラリを含めないようにする必要があります (これは必要ありません)。より優れたコンパイラまたはより優れたコンパイラ オプションを使用するだけで、10 を得ることができます。アプリケーションの速度が 30% 向上します。これは、SQL サーバーを自分でコンパイルする場合に特に重要です。Intel では、たとえば、pgcc または Cygnus CodeFusion コンパイラを使用する必要があります。新しい Fujitsu コンパイラはまだテストされていません。 MySQL のコンパイルを最適化するのに十分なエラーがないこと。
以下に私たちが作成した測定シートをいくつか示します。
-O6 を指定して pgcc を使用して何かをコンパイルすると、mysqld サーバーは gcc (文字列 99 バージョン) を使用した場合よりも 11% 高速になり、動的にリンクした場合 (-static なしで)、結果は 13% 遅くなることに注意してください。動的にリンクされた MySQL ライブラリを使用できる。Unix ソケットの代わりに TCP/IP を使用する場合、結果は Sun Pro C++ よりも 7.5% 遅くなります。 Solaris 2.5.1 では、MIT-pthreads は、単一プロセッサ上のネイティブ スレッドを使用する場合に比べて 8 ~ 12% 遅くなります (提供: TcX The MySQL)。 Linux ディストリビューションは pgcc でコンパイルされ、静的にリンクされます。
前述したように、ディスクのシークは大きなパフォーマンスのボトルネックになります。データが増大し始めると、データにアクセスするために多かれ少なかれランダムにアクセスする必要があるキャッシュが不可能になるため、この問題はますます顕著になります。読み取りには少なくとも 1 つのディスク シークが必要であり、書き込みには複数のディスク シークが必要になるため、この問題を最小限に抑えるには、シーク時間の短いディスクを使用して、使用可能なディスク スピンドルの数を増やします (これにより、シーク オーバーヘッドが軽減されます)。ファイルを別のディスクにシンボリックリンクしたり、ディスクを分割したりすることが可能です。これは、インデックス/データ ファイルを通常のデータ ディレクトリから他のディスクにシンボリックにリンクすることを意味します (これにより、シークと読み取りが行われます)。 10.2.2.1 データベースおよびテーブルへのシンボリックリンクの使用を参照してください。 分割とは、多数のディスクがあり、最初のブロックを 1 つのディスクに配置し、2 番目のブロックを 2 番目のディスクに配置することを意味します。 、n 番目のブロックは (n mod number_of_disks) 番目のディスク上にある、などです。これは、通常のデータ サイズが分割サイズよりも小さい場合 (または完全な (それに応じて配置された) 場合)、パフォーマンスがわずかに向上することを意味します。は OS と分割サイズに大きく依存するため、異なる分割サイズでアプリケーションをテストします。「10.8 独自のベンチマークの使用」を参照してください。分割の速度の違いは、分割方法に応じて大きく異なります。パラメータとディスクの数により、桁違いの違いが得られる場合があります。信頼性を確保するには、RAID 0+ 1 (スプリット + ミラー) を使用することをお勧めします。この場合、N 個のドライブのデータを保持するには 2*N 個のドライブが必要になります。お金があるなら、これがおそらく最良の選択肢です。ただし、効率的に処理するには、ボリューム管理ソフトウェアに投資する必要があるかもしれません。良い選択肢は、重要度の低いデータ (再現可能) を RAID 0 ディスクに配置し、本当に重要なデータ (ホスト情報やログ ファイルなど) を RAID 0+ 1 または RAID N ディスクに配置することです (多数の場合)。パリティ ビットの更新により、RAID N が問題になる可能性があります。簡単な変更は、noatime オプションを使用してファイル システムをマウントすることです。これにより、一部のディスク シークが回避されます。
テーブルとデータベースをデータベース ディレクトリから別の場所に移動し、新しい場所にリンクするシンボルに置き換えることができます。これを行うには、たとえば、より多くの空き領域があるファイル システムにデータベースを移動します。 MySQL は、テーブルはシンボリック リンクであることに注意し、シンボリック リンクを解決し、それが実際に指すテーブルを使用します (少なくとも Linux と Solaris では realpath() をサポートします)。 realpath() をサポートしないシステムでは、実際のパスとシンボリック リンクの両方を介してテーブルに同時にアクセスしないでください。そうすると、MySQL はデータベース リンクをサポートしません。デフォルトでは、データベース間にシンボリック リンクを作成しない限り、すべてが正常に動作します。MySQL データ ディレクトリにデータベース db1 があり、db1 を指すシンボリック リンク db2 を作成します。
シェル&> cd /path/to/datadir
シェル&> ln -s db1 db2
ここで、db1 のテーブル tbl_a については、db2 にもテーブル tbl_a が存在します。あるスレッドが db1.tbl_a を更新し、別のスレッドが db2.tbl_a を更新すると、問題が発生します。これが本当に必要な場合は、次のコードを実行します。 「mysys/mf_format.c」を変更する必要があります。
if (!lstat(to,&stat_buff)) /* シンボリックリンクかどうかを確認します */
if (S_ISLNK(stat_buff.st_mode) && realpath(to,buff))
コードを次のように変更します。
if (realpath(to,buff))