PostgreSQL(9.4)データベースを使用してRuby on Railsでアプリケーションを開発しています。私のユースケースでは、アプリケーションの全体のポイントはモデル上の非常に特定の属性を検索するため、テーブルの列は非常に頻繁に検索されます。
私は現在、使用するかどうかを決定していますinteger
タイプを、または単に(例えば、一般的な文字列型を使用character varying(255)
、Railsのではデフォルトである私は、性能差がインデックスにどうなるかわからないよう、列に対して)。
これらの列は列挙型です。可能な値の量に対して固定サイズがあります。ほとんどの列挙の長さは5を超えません。これは、アプリケーションの存続期間中、インデックスが多少固定されることを意味します。したがって、整数と文字列のインデックスはノードの数が同じになります。
ただし、インデックス付けされる文字列の長さは約20文字で、メモリ内では整数の約5倍になります(整数が4バイトで、文字列が1文字あたり1バイトの純粋なASCIIの場合、これは成り立ちます)。私は、データベースエンジンがインデックスのルックアップを行う方法を知りませんが、それが一致するまで、それは「スキャン」の文字列に必要がある場合は、正確にそして本質的には、手段は、文字列検索が遅くなる整数のルックアップよりも5倍になるということ。整数ルックアップに一致するまでの「スキャン」は20ではなく4バイトになります。これが私が想像していることです。
ルックアップ値は(整数)4です。
スキャン.................. FOUND | レコードを取得しています... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
ルックアップ値は(string) "some_val"(8バイト)です。
走査................................................. ....................................見つかった| レコードを取得しています... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
それが理にかなっていることを願っています。基本的に、整数は占有するスペースが少ないため、対応する文字列よりも速く「一致」できます。おそらくこれは完全に間違った推測ですが、私は専門家ではないので、皆さんにお願いしているのはそのためです!私が今見つけたこの答えは私の仮説を支持しているように思われるが、私は確信したい。
列の可能な値の数はどちらを使用しても変化しないため、インデックス自体は変化しません(列挙に新しい値を追加しない限り)。この場合、integer
またはの使用にパフォーマンスの違いがありますかvarchar(255)
、整数型を使用する方が理にかなっていますか?
私が尋ねる理由は、Railsのenum
型は整数を文字列キーにマッピングするが、ユーザー向けの列ではないことです。無効な値はArgumentError
検証を実行する前に発生するため、基本的に、列挙値が有効な値であることを確認することはできません。使用string
タイプは、検証が可能になるが、パフォーマンスコストがあります場合、私はむしろちょうど、検証問題を回避ハックと思います。
varchar(255)
たとえば、SQL Serverには隠された最適化はありませんvarchar(260)
。SQL Server 6.xにはそのようなことがあったかもしれませんが、これは長い間真実ではありませんでした。