テーブルを作成している最中です。
メイク(たとえば、BMW、アウディなど)がある車を保存すると、メイクをintまたはvarcharとして保存すると、クエリ速度に違いが生じますか?
そうです
SELECT * FROM table WHERE make = 5 AND ...;
より速い/遅い
SELECT * FROM table WHERE make = 'audi' AND ...;
それとも速度はほぼ同じですか?
テーブルを作成している最中です。
メイク(たとえば、BMW、アウディなど)がある車を保存すると、メイクをintまたはvarcharとして保存すると、クエリ速度に違いが生じますか?
そうです
SELECT * FROM table WHERE make = 5 AND ...;
より速い/遅い
SELECT * FROM table WHERE make = 'audi' AND ...;
それとも速度はほぼ同じですか?
回答:
Intはvarcharに比べてはるかに少ないスペースしか使用しないという単純な事実により、Intの比較はvarcharの比較よりも高速です。
これは、インデックス付けされていないアクセスとインデックス付けされたアクセスの両方に当てはまります。最も速い方法は、インデックス付きのint列です。
質問postgreqlにタグを付けたことがわかりますが、さまざまな日付タイプのスペース使用量に興味があるかもしれません。
int
フィールドは2〜8バイトを占め、通常は4 バイトで十分です(-2147483648〜+2147483647)いくつかの大まかなベンチマーク:
Postgres 9.xで400万レコード
Table A = base table with some columns
Table B = Table A + extra column id of type bigint with random numbers
Table C = Table A + extra column id of type text with random 16-char ASCII strings
8GB RAM、i7、SSDラップトップでの結果:
Size on disk: A=261MB B=292MB C=322MB
Non-indexed by id: select count(*), select by id: 450ms same on all tables
Insert* one row per TX: B=9ms/record C=9ms/record
Bulk insert* in single TX: B=140usec/record C=180usec/record
Indexed by id, select by id: B=about 200us C=about 200us
* inserts to the table already containing 4M records
したがって、この設定のように見えます。インデックスがRAMに収まる限り、bigintと16文字のテキストの速度に違いはありません。
varcharの代わりにintを使用すると、少し高速になります。速度にとってより重要なのは、クエリがレコードの検索に使用できるフィールドにインデックスを付けることです。
intを使用するもう1つの理由は、データベースを正規化することです。「Mercedes-Benz」というテキストをテーブルに何千回も保存する代わりに、そのIDを保存し、ブランド名を別のテーブルに一度保存する必要があります。
Mercedes-Benz
何千回もidを保存する代わりにですか1
。たとえば、テーブルcar_brands
、列Brands
、およびId
。行Mercedes-Benz
と1
。そして、メインテーブルの列Brands
と値1
。そしてSELECT
、その時、最初Id
はテーブルからcar_brands
、それからSELECT Something FROM main_table WHERE Brands = (SELECT Id FROM car_brands WHERE Brands = Mercedes-Benz)
。または他のアプローチ?
select something from main_table c inner join car_brands b on b.Id = c.Brands where b.Brands = 'Mercedes-Benz'
。
文字列比較と非浮動小数点の実際のパフォーマンスに分解すると、この場合、符号なしと符号付きのサイズは関係ありません。サイズは、実際にはパフォーマンスの真の違いです。1バイト+(最大126バイト)と1、2、4、または8バイトの比較です...明らかに、非浮動小数点数は文字列と浮動小数点数よりも小さいため、アセンブリでのCPUフレンドリー度が高くなります。
すべての言語での文字列の比較は、CPUが1つの命令で比較できるものよりも時間がかかります。32ビットCPUで8バイト(64ビット)を比較する場合でも、VARCHAR(2)以上より高速です。*繰り返しになりますが、生成されたアセンブリを(手動でも)確認すると、1バイトから8バイトのCPU数値ではなく、文字ごとに比較するための指示が多くなります。
さて、どれくらい速く?データの量にも依存します。5と「audi」を単に比較しているだけで、それがDBのすべてである場合、結果として生じる差はごくわずかであり、決してそれを見ることができません。CPU、実装(クライアント/サーバー、Web /スクリプトなど)によっては、DBサーバーで数百回の比較に達するまで(おそらく気付く前に数千回の比較に達するまで)、それはおそらく表示されません。
オズ
インデックスを付けるかどうかにかかわらず、intははるかに高速です(varcharが長いほど遅くなります)。
もう1つの理由:varcharフィールドのインデックスはintよりもはるかに大きくなります。より大きなテーブルの場合、数百メガバイト(および数千ページ)を意味する場合があります。インデックスを読み取るだけで多くのディスク読み取りが必要になるため、パフォーマンスが大幅に低下します。
ヒント:フィールドmakeの可能な値が決して(またはほとんど)変化しない場合は、妥協案としてENUMを使用できます。優れた速度と読みやすさを兼ね備えています。
enum
データ型がありますか?私はそれがMySQL固有だったけど。
やや相対的。はい、INTはより高速になりますが、問題はそれがあなたの状況で目立つかどうかです。VARCHARは単なる短い単語ですか、それとも長いテキストですか?テーブルには何行ありますか?行が数行しかない場合は、ほとんどの場合完全にメモリにバッファされます(頻繁に要求された場合)。その場合、大きな違いに気付くことはありません。それからもちろん、インデックスがあり、テーブルが大きくなるとより重要になります。SSDを使用すると、最適化されたクエリを使用してHDより高速になる場合があります。また、優れたディスクコントローラーは、クエリを10倍以上に高速化する場合があります。これにより、VARCHARを使用するだけの余地が生まれ、クエリの読み取りと書き込みが簡単になり(複雑な結合を作成する必要がない)、開発が高速化されます。純粋主義者はしかし、同意せず、常にすべてを正常化します。