長い文字列が格納されるカラムに対してINDEXを張る場合には、プリフィックス長を指定してみる

スポンサーリンク

CHAR、VARCHAR、BINARY、そして VARBINARY カラムには、インデックス プリフィックス長を指定する為に col_name(length) 構文を利用して、カラム値の最初に部分だけを利用するインデックスを作成する事ができます。BLOB と TEXT カラムもまたインデックスする事ができますが、プリフィックス長を与える 必要があります。。プリフィックス長は非バイナリ文字列タイプには文字で指定され、バイナリ文字列タイプにはバイトで指定されます。これは、インデックス エントリはCHAR、VARCHAR、そして TEXT カラムのそれぞれのカラム値の最初の length 文字で、そして BINARY、 VARBINARY、そして BLOB カラムのそれぞれのカラム値の最初の length バイトで成り立っているという事です。
ここに表示されているステートメントは、 name カラムの最初の10文字を利用してインデックスを作成します。


CREATE INDEX part_of_name ON customer (name(10));

もしカラム内の名前の最初の10文字が違っていれば、このインデックスは name カラム全体から作成されたインデックスよりも遅くは無いはずです。また、部分的なカラムをインデックスに利用する事でインデックス ファイルを小さくする事ができるので、ディスクのスペースを節約し、 INSERT 操作を早くする事ができます。

http://dev.mysql.com/doc/refman/5.1/ja/create-index.html

格納される文字列の形式にもよりますが、先頭数文字でINDEXとしては十分な場合(先頭数文字で、ある程度分布すれば)も多々あり、その場合には、プリフィックス長(先頭何文字をINDEXの対象とするか)を指定した方が、INDEXサイズが小さくなり、SELECTおよびINSERT、UPDATEのパフォーマンスがよくなる場合があります。(INDEXファイルのサイズが小さくなれば、その分I/Oも減るので)
VARCHAR(255)みたいなカラムに対して、プリフィックス長なしでINDEX作っているような場合には、試してみる価値があると思います。


他のDB(OraclePostgreSQLなんか)でも同じような機能あればいいんですがね。
関数(式)INDEXで同じようなことができますが、それだとSQL書く場合に、関数INDEXによる条件+もともとの条件の2つを書くことになり、SQLがとても煩雑になってしまうので。