mysqlのキーについて教えてください。


たとえばvarcharで定義されたカラム(body)に、
キーを張った場合、
100万件程度のレコードがあるテーブルでselectする際に、
条件句で、
(a) body = '123'
(b) body = 123

と記述すると、
(a)のケースではすぐに結果が来ますが、
(b)のケースでは6秒程度かかります。

カラムがintなどの数値型であれば問題ないようです。

これはどういった仕組みによるものでしょうか??


また、
perlのDBIモジュールを使っていますが、
その際は
(a)と(b)どちらで条件句はしてされるのでしょうか?

回答の条件
  • 1人2回まで
  • 登録:2008/04/25 11:18:15
  • 終了:2008/05/02 11:20:02

回答(4件)

id:pahoo No.1

pahoo回答回数5960ベストアンサー獲得回数6332008/04/25 12:07:40

ポイント23pt

データ型変換(cast)によるオーバーヘッドだと思います。

(a) body = '123'

(b) body = 123

(a) のケースでは、そのまま文字列データ型として扱うことができるので、そのままindex検索しているはずです。

(b) のケースは body に数値型(おそらくint型)として格納されるので、いったん int⇒varchar のデータ型変換を行う必要があります。型変換は逐次実行なので、index keyの効果がまったく出ていないと思われます。

id:the_yakisoba

ご回答ありがとうございます。

逆にintなどの数値型のカラムに対しては、

(a)も(b)もindexが使えているようなのですが、

この場合はvarchar =>intの変換は行われないのでしょうか?

2008/04/25 12:56:58
id:pahoo No.2

pahoo回答回数5960ベストアンサー獲得回数6332008/04/25 13:16:46

ポイント23pt

逆にintなどの数値型のカラムに対しては、

(a)も(b)もindexが使えているようなのですが、

この場合はvarchar =>intの変換は行われないのでしょうか?

これは Perl のコンテキストの問題です。


Perl は、10進整数文字([0-9])のみのスカラー列があると、クォーテーションで囲もうが囲むまいが、数値コンテキストとして評価されます。上記の例では、(a) も (b) も int型として body に格納されています。

したがって、MySQLの方のカラムの型が int であれば、型変換は発生しません。


参考サイト

id:the_yakisoba

ご回答ありがとうございます。

こちらはperlのプログラムで試してみたのではなく、

コマンドライン上でSQLを打ってみたケースで、

int型の場合は(a)も(b)も問題がありませんでした。

2008/04/25 14:40:27
id:ken33jp No.3

ken33jp回答回数928ベストアンサー獲得回数132008/04/25 19:46:43

ポイント22pt

>これはどういった仕組みによるものでしょうか??

>(a) body = '123'

>(b) body = 123

この例だと、本当は(B) はSQLの文法として間違ってるわけ。

>カラムがintなどの数値型であれば問題ないようです。

当たり前。

勉強しなおしてきてください。

id:chuken_kenkou No.4

chuken_kenkou回答回数722ベストアンサー獲得回数542008/04/25 22:46:37

ポイント22pt

本来、定数を「'」(単一引用符)で囲んだものは、文字定数です。

しかし、文字定数が、0~9のみで構成されていて、格納対象がintなどの数値のデータ型の場合、

自動的に数値←→文字の変換をしてくれるRDBMSも存在します。MySQLも、その一つです。

利用者側にとっては、数値と文字を区別せず使用できるので、便利と感じる人も

いるようです。

しかし、RDBMS側でのデータ型変換は、扱うデータ量が増えれば増える程、オーバーヘッドになります。

また、数値と文字は区別するものということに慣れている人から

見れば、違和感があったり、素人の使い方と感じます。

「数値と文字の変換」のオーバーヘッド以外には、サーバ起動後、最初の実行と2回目以降の実行では、

データがメモリ上にキャッシュ(バッファリング)されていて、性能向上したように見える場合もあります。

http://q.hatena.ne.jp/だみー

  • id:taknt
    考えられる原因は、比較する値が数値なので、項目側を いちいち数値に変換して 比較しているためだと思われます。

    ま、推測なので コメントで。
  • id:pahoo
    #2の補足です。
    MySQLは、カラムが数値型の場合、シングルクォーテーションで囲んだ10進整数文字([0-9])を数値として見なすという仕様になっています。(他のRDBMSは文字列型と見なします)
    したがって、型変換が発生していないものと思われます。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません