web-dev-qa-db-ja.com

複数の列のフルテキストインデックスはどのように機能しますか?

3列にフルテキストインデックスを追加する場合、3列に1つのインデックスを追加しますか、それとも3つの個別のインデックスを追加しますか?

現時点では、次のようにFULLTEXTを使用しているため、これを尋ねます。

ALTER TABLE myTable ADD FULLTEXT all3colsIndex (col1,col2,col3);
SELECT * FROM myTable WHERE MATCH (col1, col2, col3) AGAINST ('Word');

検索インターフェイスにユーザーオプションを追加しました。ユーザーは、検索から列の1つを削除できます。したがって、インデックスを失うことなくこれを行うことができます。ここでは、3つの列のうち2つだけを使用しています。

ALTER TABLE myTable ADD FULLTEXT all3colsIndex (col1,col2,col3);
If (UserOptionRemoveCol == "selected") {
    SELECT * FROM myTable WHERE MATCH (col1, col2) AGAINST ('Word');
} else {
    SELECT * FROM myTable WHERE MATCH (col1, col2, col3) AGAINST ('Word');
}

または、2つの列と3つの列に新しいFULLTEXTインデックスを作成する必要がありますか?

ALTER TABLE myTable ADD FULLTEXT all3colsIndex (col1,col2,col3);
ALTER TABLE myTable ADD FULLTEXT 2colsIndex (col1,col2);
18
TheCarver

CREATE FULLTEXT INDEX のマニュアルを見ると、column_nameを次のように繰り返すことで複数の列を指定できることがわかります。

CREATE FULLTEXT INDEX ON table_name (column_name1 [...], column_name2 [...]) ...

この情報を考えると、列にわたる単一のインデックスを作成すると思います。さらに、複合インデックスに関しては、左から右のルールで機能すると想定しています(次のステートメントの実行プランを確認して、これを確認します)。したがって、(col1, col2, col3)の複合インデックスを使用するには、その順序で選択する必要があります(SELECT col1, col2 ...)。 col2を呼び出す場合、インデックスは使用されません。

8
Kermit

MySQLでは、使用する予定の列のセットごとに個別のインデックスを作成する必要があります(自然言語検索を使用している場合。これは、ブール検索では異なる場合があります)。

手動 から:

自然言語の全文検索の場合、MATCH()関数で指定された列は、テーブルの一部のFULLTEXTインデックスに含まれている列と同じである必要があります。 [...]タイトルまたは本文を個別に検索する場合は、列ごとに個別のFULLTEXTインデックスを作成する必要があります。

4
bearoff

タイプFULLTEXTのインデックスは1つだけ作成されます。そのインデックスは、必要に応じて複数の列に「またがる」でしょう。ただし、インデックス自体は、wordsほど列にインデックスを付けていません。 ドキュメント から:

InnoDB FULLTEXTインデックスには、転置インデックス設計があります。転置インデックスには、単語のリストが格納され、各単語について、その単語が表示されるドキュメントのリストが格納されます。[...]

3つの列をグループ化する1つのFULLTEXTを作成する場合、または1つだけをグループ化する3つのFULLTEXTを作成する場合、これらの列は事実上、FULLTEXTメタデータテーブルのエントリで構成されます。

着信ドキュメントがトークン化されると、個々の単語(「トークン」とも呼ばれます)が、位置情報および関連するドキュメントID(DOC_ID)とともにインデックステーブルに挿入されます。

基本的に、単語の格納は列の元の分離から抽象化されているため、複数列のFULLTEXTインデックスと複数の単一列のFULLTEXTインデックスは同じように機能するようです。