2

この投稿を見つけました:

5000 レコードのテーブルで MySQL のようなクエリの実行が非常に遅くなる

そして、彼が言う asaph の投稿を理解することに興味があります。

select * from customer where '%a%' のようなコードはインデックスを使用できない可能性があるため、高速であるとは思いません。すべてのレコードをチェックする必要があります。select * from customer where code like 'a%' はインデックスを使用できる可能性があるため、可能であれば検討してください。

誰かが 2 つの select ステートメントの違いを説明できますか? ワイルドカードは 1 つしかなく、"a" で始まるものしか見つからないことはわかっています。しかし、なぜそれを索引付けできるのでしょうか?

4

3 に答える 3

5

MySQL の B ツリー インデックスの実際の詳細はこれよりも複雑ですが、ほとんどの場合、列にインデックスを設定すると、MySQL エンジンはその列によって順序付けられSELECTているかのようにテーブルに対して s を実行できると言えます。

code列にインデックスがあり、レコードを検索している場合、code LIKE 'a%'すべての MySQL (または十分に賢い限り、他の SQL パッケージ) がしなければならないのは、'a の先頭からすべてのレコードを吐き出すことです。 ' から 'b' の先頭まで。ただし、レコード where を検索している場合、行が WHERE 句に一致するかどうかとインデックス内の位置との単純な関係がないためcode LIKE '%a%'、テーブルが既に によって並べ替えられていても役に立ちません。したがって、2 番目のクエリでは、テーブル内のすべての行のエントリのcodeすべての文字をチェックする以外に、データベースが合理的にできることは何もありません(既に結果がキャッシュされている場合を除きます)。code

これは直感的に理解するのがかなり簡単です。なぜなら、自分自身が人間として合理的に類似したことを行うことを想像できるからです。オックスフォード英語辞典で「a」で始まるすべての単語を見つけたい場合は、「a」の先頭から「b」の先頭までのすべてのページを調べれば、表示されるすべての単語が単語になります。 「あ」から始まります。辞書内のどこかに「a」が含まれるすべての単語を見つけたい場合、並べ替えられた辞書はあまり役に立ちません。あなたが十分に洗練されている場合は、辞書の順序を少し利用することができます(辞書の最初の 'b...' 単語の前のすべての単語には 'a' が含まれているという知識を使用するなど)。最終的にあなたの

于 2013-03-07T21:38:32.443 に答える
3

マニュアルから:

ほとんどの MySQL インデックス ( PRIMARY KEYUNIQUEINDEX、およびFULLTEXT) は B ツリーに格納されます。B ツリー インデックスは、、、、、、、または演算子を使用する式=の列比較に使用できます。次のステートメントはインデックスを使用しません。>>=<<=BETWEENSELECT

SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';

引数 toがワイルドカード文字で始まらない定数文字列である場合、インデックスはLIKE比較にも使用できます。LIKEたとえば、次のSELECT ステートメントはインデックスを使用します。

SELECT * FROM tbl_name WHERE key_col LIKE 'Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%';
于 2013-03-07T21:36:05.643 に答える
2

MySQL はBTREEインデックスを使用します。

LIKE を先頭にワイルドカードを使用して文字列比較を行う場合、インデックスを使用して結果を絞り込むことができないため、MySQL がテーブル スキャンを実行する方が高速です。

LIKE を末尾のワイルドカードとともに使用して文字列を比較する場合は、スキャンする必要があるレコードが少ないため、インデックスを使用する方が高速です。

于 2013-03-07T21:41:01.370 に答える