2011-02-04 45 views
7

私は大きなMyISAMテーブルを持っています。 100万行に近づいています。これは基本的にアイテムのリストとそれらに関するいくつかの情報です。MySQL SELECTでは、より大きい値と等しい値との差がメジャーなのはなぜですか?

  • プライマリ:アイテムID
  • 日付(年月日)とCOL(INT)

    は、2つのインデックスがあります。 〜0.0005秒で

    SELECT * FROM table WHERE date = '2011-02-01' AND col < 5 LIMIT 10 
    
    SELECT * FROM table WHERE date < '2011-02-01' AND col < 5 LIMIT 10 
    

    最初の1が終了すると〜0.05秒で秒:

は、私は2つのクエリを実行します。それは100倍の違いです。これらの両方がほぼ同じスピードで動作することを期待するのは間違っていますか?私は指標をよく理解してはいけません。 2番目のクエリを高速化するにはどうすればよいですか?

+0

、どのように多くのレコードは、最初の述語が一致しますか? –

+0

等価の場合は40,000、それ以下の場合は55,000なので、大きな違いはありません – burger

+0

@bigmacインデックスフォーマットを変更して何が起こるか試してみてください。 –

答えて

2

Mysqlにかかわらず、それは基本的なアルゴリズムの理論に沸きます。

大きなセットでは、より大きい演算と小なり演算は、アイデンティティ演算よりも遅くなります。 大きなデータセットの場合、より小さいかより大きいかを判断するための理想的なデータ構造は自己平衡ツリー(バイナリまたはnツリー)です。 自己バランス木では、より小さい/より大きいすべてを見つける最悪のシナリオはログnです。

ID照合の理想的なデータ構造はハッシュテーブルです。ハッシュテーブルのパフォーマンスは、一般にO(1)という固定時間です。しかし、ハッシュテーブルは、より大きい/少ないためには良くありません。

一般に、バランスのとれたツリーは、ハッシュテーブルよりもわずかに性能が劣ります(ハスケルがハッシュテーブル用にツリーを使用する方法です)。

このように、MySQLはその<は、>以下=

旧回答よりも遅いことを驚かしないものの関わらず:特に(最初の1つは「=」ので、Hashtableの検索のようなものですので

インデックスがハッシュテーブルの場合)、索引のようなツリーでうまくいくかもしれない2番目のインデックスよりも速くなります。

MySqlではインデックスフォーマットを設定することができるので、それを変更することはできますが、最初のものは常に2番目のものより速く実行されます。

+0

CREATE INDEXのドキュメントへのリンク:http://dev.mysql.com/doc/refman/5.0/en/create-index.html –

+0

私のテーブルはMyISAMなので、私はBTREEインデックスしか持てません。 InnoDBもBTREEだけです。私はまだ気づいていないかもしれない他の警告を含んでいるかもしれないので、より主流のストレージエンジンに切り替えることを心配しています。 – burger

+0

これはまた役に立つかもしれません。http://dev.mysql.com/doc/refman/5.5/en/index-btree-hash.html –

1

第1のものは、第2のものがスキャンのために行くデータのシークオーバーを実行する。スキャンは常に時間差を求めるよりもコストがかかります。

このように、スキャンとは、シーク時にページ番号に直接ジャンプする本のすべてのページを実行することを意味します。

これは役に立ちます。

2

私はあなたが日付の列にインデックスを持っていると仮定しています。 最初のクエリはインデックスを使用し、2番目のクエリはおそらくリニアスキャンを行います(データの少なくとも一部)。ダイレクトフェッチは常にリニアスキャンより高​​速です。

2

MySQLはインデックスをデフォルトでBTREEに格納します。一般的なハッシングはありません。

パフォーマンスの違いについての簡単な答えは、<フォームが=フォームより多くのノードを評価するということです。サイズBのソートされたツリーノードを昇順で

2011-01-01, col=1, row_ptr 
2011-01-01, col=2, row_ptr 
2011-01-01, col=3, row_ptr 
etc... 
2011-02-01, col=1, row_ptr 
2011-02-01, col=2, row_ptr 
2011-02-01, col=3, row_ptr 
etc... 
2011-02-02, col=1, row_ptr 
2011-02-02, col=2, row_ptr 
etc... 

...(2011-01-:

あなたがそこに持っているインデックス(日付、COL)はおおよそ電話帳のような値を格納します01、col = 1)<(2011-01-01、col = 2)<(2011-01-02、col = 1)。 「A」

  • で始まる姓が「Smith」と最初の名前を持つすべての電話番号の前に来るすべての電話番号を検索して下さい

    1. あなたの質問は、本質的に違いを求めています 'Smith'で始まり、最初に 'A'で始まる名前があります

    なぜ#1が#2よりずっと速いのかは明らかです。

    また、メモリ/ディスク転送効率とヒープ割り当て(=少ない転送回数の場合は<)の考慮事項がありますが、それほど重要ではありませんが、データの分布と特定の場所に大きく依存します。 2011-02-01、col = min(col)キーレコード。