もっとも基本的な最適化の 1 つにデータ (およびインデックス) が占めるディスク領域を可能なかぎり少なくすることがあります。これで、ディスクの読み取りが高速化し、使用メモリーも一般に減少するため、大幅な改善が図れます。カラムが小さければインデックス設定で消費されるリソースも少なくなります。
MySQL では多様なテーブル型とレコード形式がサポートされます。テーブルごとに、使用するストレージとインデックス設定方法を決定できます。適切なテーブル形式を選択することで、パフォーマンスを大幅に改善できます。Storage Engines を参照してください。
ここで紹介する技法を使用すると、テーブルのパフォーマンス改善とストレージ領域の最小化を図ることができます。
できるかぎり効率性の高い (最小)
の型を使用する。MySQL
にはディスク領域とメモリーを節約できる専用の型がある。可能な場合は、小さなテーブルの取得には小さな整数型を使用する。たとえば、INT
より、25%スペース使用量の少ない
MEDIUMINT
のほうが適している場合もしばしばあります。
できるかぎり、カラムに
NOT NULL
を宣言します。これですべてが高速化され、1
カラム当たり 1
ビットを節約できます。アプリケーションで実際に
NULL
が必要な場合は、必ず使用する必要があるため、注意が必要です。デフォルトですべてのカラムにこれを設定することは避けます。
MyISAM
テーブルでは、可変長カラム
(VARCHAR
、TEXT
、あるいは
BLOB
など)
がまったくない場合は固定長レコード形式を使用します。これで速度が上りますが、領域の消費も増えます。詳しくはMyISAM
Table Storage Formatsを参照してください。たとえ
CREATE TABLE
オプション
ROW_FORMAT=FIXED
が使用された
VARCHAR
カラムがあっても、固定長行が必要な場合のヒントが得られます。
InnoDB
はコンパクトストレージフォーマットを使用します。MySQL
5.0.3
以前のバージョンでは、InnoDB
行は固定サイズカラムにたいしても、カラム数やカラム長さといった冗長な情報を含みます。デフォルトでは、コンパクトフォーマット
(ROW_FORMAT=COMPACT
)
でテーブルが作成されます。MySQL
の旧バージョンにダウングレードをしたい場合、ROW_FORMAT=REDUNDANT
で古いフォーマットを要求できます。
コンパクト行フォーマットを使用すると、行のストレージ領域が約 20% 減少しますが、一部の操作では CPU 使用率が高くなります。キャッシュヒット率とディスク速度によって制限されている通常の作業負荷であれば、速度が向上する可能性が高くなります。まれに、CPU 速度によって制限されている場合は、速度が低下する可能性があります。
コンパクト InnoDB
フォーマットは UTF8 データを含む
CHAR
カラムがどのように格納されるかも変更します。UTF-8
エンコードキャラクタの最大長が 3
バイトであることを前提に、ROW_FORMAT=REDUNDANT
では、UTF-8
CHAR(
は 3 × N
)N
バイトを使用します。多くの言語は主にシングルバイト
UTF-8
キャラクタを用いてかかれるため、固定保存長はスペースを無駄に使用します。ROW_FORMAT=COMPACT
フォーマットでは、InnoDB
は N
から 3 ×
N
バイトのストレージ可変容量をこれらカラムに割り当てます
(必要であれば末尾のスペースを取り除いて行う)。最小のストレージ長は、ある場合に適切な更新が行われるように、N
バイトとして保持されます。
テーブルのプライマリインデックスを可能なかぎり短くします。これで、レコードの識別が容易になり効率化が図れます。
インデックスの作成は必要なものだけに限定します。インデックスは取り出しに優れていますが、高速保存が必要な場合は適されません。カラムの組み合わせを使用してテーブルを検索し、テーブルにアクセスする場合がほとんどであれば、インデックスを作成します。インデックスの最初の部分は、もっとも使用頻度の高いカラムにする必要があります。テーブルの検索時に、「常に」多数のカラムを使用する場合は、もっとも重複の多いカラムをインデックスの最初のカラムに使用すると、インデックスの圧縮を改善できます。
文字列の最初の数文字に、一意の接頭辞があるカラムが多い場合は、この接頭辞のみをインデックス作成したほうがよりよくなります。MySQL
はカラムのもっとも左側の部分インデックス作成をサポートします
(項8.1.13. 「CREATE INDEX
構文」を参照)。短いインデックスの速度が速い理由は、占有ディスク領域が小さいことだけではなく、インデックスキャッシュでのヒットが多くなり、所要ディスクシークが少なくなることにもよります。項4.5.3. 「サーバーパラメータのチューニング」
を参照してください。
状況によっては、スキャンの頻度が高いテーブルを 2 つに分割したほうが有利な場合もあります。これは特に、動的テーブルで、テーブルスキャンの際に対応する行の検索に小さな静的テーブルの使用が可能である場合にあてはまります。