私はSpring-Javaとmysqlで働いています。
サイズ100k records
のテーブルをクエリする必要があります。テーブルには10列あります。そして、私のSQL選択クエリでは、たとえば4列で%text%検索を行うようなクエリを作成する必要があります。これらの4つの列はvarchar(200)であり、平均テキストサイズは30文字です。
私はいくつかのブログを読み、SO回答をインデックスについて理解するために読んだ後、この質問に行きました。
これらの4つの列を個別にFULLTEXT
インデックスにすると、同様のクエリの実行時間が異なりますか?
ありがとうございました
「標準」インデックスの仕組みを理解する手助けをさせてください。
ほとんどのデータベースインデックスは B-Trees です(バイナリツリーと混同しないでください)。簡単に言えば、インデックス付きの列をクエリすると、 バイナリ検索 が実行されます。バイナリ検索は一般的にO(log(n))で実行されるため、それらの行が多数ある場合でも、個々の行を非常に高速に見つけることができます。データベースは、ロードおよびインデックスはそれほど多くのメモリを必要とせず、必要なディスク読み取りが少ないため、テーブルを並べ替えます。
ここで、値のバイナリ検索を試みたが、値の正確な始まりまたは終わりがわからないと想像してください。二分探索は基本的に不可能であり、すべての可能性を見つけるには、ほぼツリー全体を走査する必要があります。
もちろん、これより巧妙なテクニックがあります。 MySQLはそのようなばかげたものではなく、この問題に対して Boyer-Mooreアルゴリズム を使用しますが、パフォーマンスへの影響がないわけではありません。
全文検索インデックスはもちろん役に立ちます。完全に異なるデータ構造( Tries 、 Suffix-Trees )を使用します。 MySQLのマニュアルを読んでいると、全文検索が非常に簡単だという印象も受けます。
ただし、ほとんどのシステムでは、フルテキスト検索で良好なパフォーマンスを維持するために、管理者によるメンテナンス/ハウスキーピングが必要です。多くの場合、フルテキストインデックスは、インデックス付きテキストのトークン用の「マッピング/インデックス」テーブルを保持します。これらは断片化する傾向があり、インデックスが不必要に大きくなると、クエリの応答時間に影響を与える可能性があります。したがって、時々、それらはデフラグされ、最適化されるべきです。あなたはそれを調べたいかもしれません。
%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();
上記の回答に加えて、Bツリー、クラスター、およびフルテキストインデックスは複数にすることができ、左から右に機能します。例:
where `1` like '%1%' and `2` like '%2%' and `3` like '%3%'
(1
、2
、3
)良好なパフォーマンスを実現します。
Where条件に列が1つしかない場合、その列のフルテキストインデックスによってパフォーマンスが大幅に向上します。
ちなみに、MyISAMエンジンとInnoDBエンジンはどちらもMySQLのフルテキストインデックスをサポートしています> = 5.6