sql >> データベース >  >> RDS >> Mysql

フルテキストインデックスと複合インデックス、およびそれらがクエリに与える影響

    あなたの質問を理解すると、MATCH AGAINSTがFULLTEXTインデックスを使用し、MySQLが残りのWHERE句をどのように適用するのか疑問に思っていることを知っています(つまり、テーブルスキャンまたはインデックス付きルックアップを実行します)。

    これがあなたのテーブルについて私が想定していることです:それはいくつかのid列にPRIMARYKEYとFULLTEXTインデックスを持っています。

    したがって、最初に、MySQLは決してありません 都市/州のWHERE句にはFULLTEXTインデックスを使用します。なんで? FULLTEXTインデックスは、MATCHAGAINSTでのみ適用されるためです。 こちら を参照してください。 最初の一連の箇条書きの後の段落(目次の箇条書きではありません)。

    編集: あなたの場合、テーブルに10行しかない場合、MySQLはMATCH AGAINSTにFULLTEXTインデックスを適用し、それらの結果に対してテーブルスキャンを実行して都市/州のWHEREを適用します。

    では、BTREEインデックスを市と州に追加するとどうなるでしょうか?

    CREATE INDEX city__state ON table (city(10),state(2)) USING BTREE;
    

    MySQLは1つしか使用できません 単純な選択であるため、このクエリのインデックス。 どちらかになります フルテキストをまたは使用します BTREE。 1つのインデックスとは、マルチパートインデックスの1つの列ではなく、1つのインデックス定義を意味することに注意してください。とにかく、これは次に、どちらが行うかという質問をします。 使用しますか?

    それはテーブル分析に依存します。 MySQLは推定を試みます (最後のOPTIMIZE TABLEのテーブル統計に基づく)どのインデックスが最も多くのレコードを削除しますか。都市/州のWHEREで10レコードまで減少し、MATCH AGAINSTで100レコードまでしか減少しない場合、MySQLはcity__stateインデックスを最初に使用します。 都市/州のWHEREの場合は、MATCHAGAINSTのテーブルスキャンを実行します。

    一方、MATCH_AGAINSTで10レコードまで減少し、都市/州のWHEREで1000レコードまで減少した場合、MySQLは最初にFULLTEXTインデックスを適用し、都市と州のテーブルスキャンを実行します。

    一番下の行はカーディナリティです あなたのインデックスの。基本的に、インデックスに入力される値はどの程度一意ですか?テーブル内のすべてのレコードで都市がオークランドに設定されている場合、それはあまり一意のキーではないため、 city ='Oakland' レコードの数をそれほど減らすことはありません。その場合、あなたのcity__stateインデックスのカーディナリティは低いと言えます。 。

    したがって、フルテキストインデックスの単語の90%が「ジョン」である場合、まったく同じ理由で、それはあまり役に立ちません。

    スペースとUPDATE/DELETE / INSERTオーバーヘッドに余裕がある場合は、BTREEインデックスを追加し、MySQLに使用するインデックスを決定させることをお勧めします。私の経験では、彼は通常、適切なものを選ぶのに非常に優れた仕事をしています。

    それがあなたの質問に答えることを願っています。

    編集: ちなみに、BTREEインデックスに適切なサイズを選択していることを確認してください(私の例では、都市の最初の10文字を選択しました)。これは明らかにカーディナリティに大きな影響を与えます。 city(1)を選択した場合、city(10)を選択した場合よりも明らかにカーディナリティが低くなります。

    編集2: インデックスが最も多くのレコードを削除するMySQLのクエリプラン(推定)は、EXPLAINに表示されるものです。



    1. なぜPostgreSQLを学ぶ必要があるのですか?

    2. MySQLの左結合をPHPと2つの別々のクエリでループする

    3. Wiresharkを使用してmysqlクエリSQLを明確にキャプチャする方法

    4. 修正:「現在のデータベースのバックアップがないため、バックアップログを実行できません。」 SQL Server /SQLEdgeで