web-dev-qa-db-ja.com

likeクエリはインデックス付きテーブルでどのように機能しますか

私はSpring-Javaとmysqlで働いています。

サイズ100k recordsのテーブルをクエリする必要があります。テーブルには10列あります。そして、私のSQL選択クエリでは、たとえば4列で%text%検索を行うようなクエリを作成する必要があります。これらの4つの列はvarchar(200)であり、平均テキストサイズは30文字です。

私はいくつかのブログを読み、SO回答をインデックスについて理解するために読んだ後、この質問に行きました。

これらの4つの列を個別にFULLTEXTインデックスにすると、同様のクエリの実行時間が異なりますか?

ありがとうございました

3
Naman Gala

「標準」インデックスの仕組みを理解する手助けをさせてください。

ほとんどのデータベースインデックスは B-Trees です(バイナリツリーと混同しないでください)。簡単に言えば、インデックス付きの列をクエリすると、 バイナリ検索 が実行されます。バイナリ検索は一般的にO(log(n))で実行されるため、それらの行が多数ある場合でも、個々の行を非常に高速に見つけることができます。データベースは、ロードおよびインデックスはそれほど多くのメモリを必要とせず、必要なディスク読み取りが少ないため、テーブルを並べ替えます。

ここで、値のバイナリ検索を試みたが、値の正確な始まりまたは終わりがわからないと想像してください。二分探索は基本的に不可能であり、すべての可能性を見つけるには、ほぼツリー全体を走査する必要があります。

もちろん、これより巧妙なテクニックがあります。 MySQLはそのようなばかげたものではなく、この問題に対して Boyer-Mooreアルゴリズム を使用しますが、パフォーマンスへの影響がないわけではありません。

全文検索インデックスはもちろん役に立ちます。完全に異なるデータ構造( TriesSuffix-Trees )を使用します。 MySQLのマニュアルを読んでいると、全文検索が非常に簡単だという印象も受けます。

ただし、ほとんどのシステムでは、フルテキスト検索で良好なパフォーマンスを維持するために、管理者によるメンテナンス/ハウスキーピングが必要です。多くの場合、フルテキストインデックスは、インデックス付きテキストのトークン用の「マッピング/インデックス」テーブルを保持します。これらは断片化する傾向があり、インデックスが不必要に大きくなると、クエリの応答時間に影響を与える可能性があります。したがって、時々、それらはデフラグされ、最適化されるべきです。あなたはそれを調べたいかもしれません。

1
Falcon

%a%のようなクエリを実行したい場合は、

リポジトリ(インターフェース)コード

@Query("SELECT p from Project p where p.skillSetRequired LIKE :skill% order by p.projectDeadline")
public Optional<List<Project>> findProjectsBySkill(@Param("skill") String skill);

また、findprojectsBySkillメソッドを呼び出しながら、コントローラからスキルをskill = '%' + skillとして渡すことができます

たとえば、コントローラのコードは次のようになります

@Autowired
private Repository repository;

List<Project>=repository.findprojectsBySkill('%'+skill).get();
1
Archit Puri

上記の回答に加えて、Bツリー、クラスター、およびフルテキストインデックスは複数にすることができ、左から右に機能します。例:

where `1` like '%1%' and `2` like '%2%' and `3` like '%3%'

123)良好なパフォーマンスを実現します。

Where条件に列が1つしかない場合、その列のフルテキストインデックスによってパフォーマンスが大幅に向上します。

ちなみに、MyISAMエンジンとInnoDBエンジンはどちらもMySQLのフルテキストインデックスをサポートしています> = 5.6

0
Sam Ivichuk