SQL SELECTの速度intとvarchar


110

テーブルを作成している最中です。

メイク(たとえば、BMW、アウディなど)がある車を保存すると、メイクをintまたはvarcharとして保存すると、クエリ速度に違いが生じますか?

そうです

SELECT * FROM table WHERE make = 5 AND ...;

より速い/遅い

SELECT * FROM table WHERE make = 'audi' AND ...;

それとも速度はほぼ同じですか?

回答:


99

Intはvarcharに比べてはるかに少ないスペースしか使用しないという単純な事実により、Intの比較はvarcharの比較よりも高速です。

これは、インデックス付けされていないアクセスとインデックス付けされたアクセスの両方に当てはまります。最も速い方法は、インデックス付きのint列です。


質問postgreqlにタグを付けたことがわかりますが、さまざまな日付タイプのスペース使用量に興味があるかもしれません。


13
7.4ページを参照しています。最近のバージョンでは、126バイト未満の場合、1バイト+長さが必要です。また、文字列がはるかに遅い理由は、照合に敏感な比較が非常に高くつくことです-文字列がより多くのスペースをとるということではありません。もちろん、最終結果は同じです。
Magnus Hagander 2010

@マグナス-ヘッズアップをありがとう。担当者が十分だと思いますので、お気軽に私の回答を編集してください。
ロバートムンテアヌ

「文字列がより多くのスペースをとらない」...最小サイズを超える文字の文字列は、高精度の数値よりもはるかに多くのスペースを占めます。数値(単数)には固定単位があるため、文字列は常に集約型です。文字列の1文字あたり4バイトの64ビット数値の場合は8バイト。長さバイトまたは構造体を含みます。または信じられないほど素朴な実装のための別のターミネーター文字...
MrMesees

@RobertMunteanuこんにちは、ロバート、申し訳ありません。これは古い投稿ですが、次の点を確認してください...整数を照会するには、各文字列の列を別のテーブルにリンクする必要があります(関係)。ただし、これは、クエリごとに追加の結合操作が必要であることを意味します。このトレードオフが価値があるかどうかをどのように判断しますか?ありがとうございました!
AiRiFiEd 2017年

2
「intの比較はvarcharの比較よりも高速です。これは、intがvarcharに比べて占有するスペースが少ないという単純な事実のためです」-これは一般的には当てはまりません。使用するDBMSと、挿入する正確なデータ型および文字列によっては、(たとえば)8バイトの整数が、3〜4文字の平均長のテキストIDを保持するASCII varcharよりも長い場合があります。したがって、この答えは不正確であり、特定のコンテキストや実験結果がないため、実際には質問に答えることはできません。varcharはintよりもはるかに多くのスペースを使用できることを誰もが知っていますが、そうする必要はありません。
Marcin Wojnarski

36

いくつかの大まかなベンチマーク:

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文字のテキストの速度に違いはありません。


6
とても興味深い。違いが無視できるのはなぜですか?
Chibueze Opata 2017

18

varcharの代わりにintを使用すると、少し高速になります。速度にとってより重要なのは、クエリがレコードの検索に使用できるフィールドにインデックスを付けることです。

intを使用するもう1つの理由は、データベースを正規化することです。「Mercedes-Benz」というテキストをテーブルに何千回も保存する代わりに、そのIDを保存し、ブランド名を別のテーブルに一度保存する必要があります。


詳しく説明していただけますか?Mercedes-Benz何千回もidを保存する代わりにですか1。たとえば、テーブルcar_brands、列Brands、およびId。行Mercedes-Benz1。そして、メインテーブルの列Brandsと値1。そしてSELECT、その時、最初Idはテーブルからcar_brands、それからSELECT Something FROM main_table WHERE Brands = (SELECT Id FROM car_brands WHERE Brands = Mercedes-Benz)。または他のアプローチ?
Andris

3
@ user2118559:はい、そのように保存します。データを取得するには、通常、サブクエリではなく結合を使用しますselect something from main_table c inner join car_brands b on b.Id = c.Brands where b.Brands = 'Mercedes-Benz'
グッファ

なぜ反対票か。何が間違っていると思うかを説明しなければ、答えを改善することはできません。
Guffa 2016年

8

文字列比較と非浮動小数点の実際のパフォーマンスに分解すると、この場合、符号なしと符号付きのサイズは関係ありません。サイズは、実際にはパフォーマンスの真の違いです。1バイト+(最大126バイト)と1、2、4、または8バイトの比較です...明らかに、非浮動小数点数は文字列と浮動小数点数よりも小さいため、アセンブリでのCPUフレンドリー度が高くなります。

すべての言語での文字列の比較は、CPUが1つの命令で比較できるものよりも時間がかかります。32ビットCPUで8バイト(64ビット)を比較する場合でも、VARCHAR(2)以上より高速です。*繰り返しになりますが、生成されたアセンブリを(手動でも)確認すると、1バイトから8バイトのCPU数値ではなく、文字ごとに比較するための指示が多くなります。

さて、どれくらい速く?データの量にも依存します。5と「audi」を単に比較しているだけで、それがDBのすべてである場合、結果として生じる差はごくわずかであり、決してそれを見ることができません。CPU、実装(クライアント/サーバー、Web /スクリプトなど)によっては、DBサーバーで数百回の比較に達するまで(おそらく気付く前に数千回の比較に達するまで)、それはおそらく表示されません。

  • ハッシュ比較に関する誤った論争を無効にするため。ほとんどのハッシュアルゴリズム自体は低速であるため、CRC64以下などのメリットはありません。12年以上にわたり、私は複数郡の検索エンジン向けに7年間、信用調査会社向けに検索アルゴリズムを開発しました。たとえば、電話番号、郵便番号、通貨* 1000(保管)通貨div 1000(取得)でも、数値で保持できるものはすべて、比較ではDECIMALより高速です。

オズ


6

インデックスを付けるかどうかにかかわらず、intははるかに高速です(varcharが長いほど遅くなります)。

もう1つの理由:varcharフィールドのインデックスはintよりもはるかに大きくなります。より大きなテーブルの場合、数百メガバイト(および数千ページ)を意味する場合があります。インデックスを読み取るだけで多くのディスク読み取りが必要になるため、パフォーマンスが大幅に低下します。


3
たとえば、「audi」の500万件のレコードの場合、インデックスには「audi」の文字列の1つのコピーとprimary_keyの500万件の整数だけしか保持されませんか?サイズの違いは本当に大きなものでしょうか、それはvcharですか、整数ですか?
lulalala 2017年

あなたは正しいルラララですが、ランダムな文字列を含む列の場合、答えは十分に公正です。
Awais fiaz


3

ヒント:フィールドmakeの可能な値が決して(またはほとんど)変化しない場合は、妥協案としてENUMを使用できます。優れた速度と読みやすさを兼ね備えています。


1
興味深いのですが、ENUMとintの速度の違いはどうでしょうか?
googletorp 2010

PostgresSQLにはenumデータ型がありますか?私はそれがMySQL固有だったけど。
ロバートムンテアヌ

PostgresにはENUMがありますが、MySQLとまったく同じ方法で実装されているとは思いません。postgresql.org/docs/current/static/datatype-enum.html
googletorp 2010

2
パフォーマンスに関しては、ENUMは検索フィールドのintとほぼ同じように実行する必要がありますが、ターゲットリストのvarcharとして実行します(intだけでなく、一致する行の文字列全体をクライアントに転送する必要があるため)
Magnus Hagander

1
MySQLでenumを使用しない理由についての興味深い記事(火に燃料を追加するためだけに:D)
Wilt

1

あなたがオンにすると、インデックスフィールドのいずれかで、それが速くなります。あなたの質問については、私intはよりも速いと思いますvarchar


0

やや相対的。はい、INTはより高速になりますが、問題はそれがあなたの状況で目立つかどうかです。VARCHARは単なる短い単語ですか、それとも長いテキストですか?テーブルには何行ありますか?行が数行しかない場合は、ほとんどの場合完全にメモリにバッファされます(頻繁に要求された場合)。その場合、大きな違いに気付くことはありません。それからもちろん、インデックスがあり、テーブルが大きくなるとより重要になります。SSDを使用すると、最適化されたクエリを使用してHDより高速になる場合があります。また、優れたディスクコントローラーは、クエリを10倍以上に高速化する場合があります。これにより、VARCHARを使用するだけの余地が生まれ、クエリの読み取りと書き込みが簡単になり(複雑な結合を作成する必要がない)、開発が高速化されます。純粋主義者はしかし、同意せず、常にすべてを正常化します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.