全文索引を使用するmysql-queryのパフォーマンスに少し問題があります。
次のクエリ
SELECT Mention.id
FROM mentions AS Mention
WHERE (MATCH (`Mention`.`title_text`, `Mention`.`content_text`, `Mention`.`author_text`)
AGAINST ('"hannover 96"' IN BOOLEAN MODE))
約3秒かかります。
Fulltext-conditionを次のように変更した場合
SELECT Mention.id
FROM mentions AS Mention
WHERE (MATCH (`Mention`.`title_text`, `Mention`.`content_text`, `Mention`.`author_text`)
AGAINST ('+hannover +96' IN BOOLEAN MODE))
クエリの所要時間は約0.001秒です。
それで、最初のクエリのパフォーマンスを向上させる可能性はありますか? 「hannover 96」という文字列全体を検索することが重要です。hannoverと96を含むレコードは検索しないでください。
ヒントをありがとう!
宜しくお願いします、
ティモ
クエリのWHERE
句が完全に異なるものを要求しています
MATCH
句で言及されている3つの列内の正確な文字列hannover 96
。hannover
句で言及されている3つの列内の2つの文字列MATCH
および96
。フルテキストインデックスはトークンを非常にうまくインデックス化します。したがって、複数のトークンを含む正確な文字列は、処理に時間がかかるはずです。
hannover 96
をより速く見つける唯一の方法は、サブクエリを使用することです。
SELECT B.* FROM
(SELECT Mention.id FROM mentions AS Mention
WHERE (MATCH (`Mention`.`title_text`,`Mention`.`content_text`,`Mention`.`author_text`)
AGAINST ('+hannover +96' IN BOOLEAN MODE))) A
INNER JOIN Mention B USING (id)
WHERE LOCATE('hannover 96',CONCAT(title_text,content_text,author_text)) > 0;
または
SELECT B.* FROM
(SELECT Mention.id FROM mentions AS Mention
WHERE (MATCH (`Mention`.`title_text`,`Mention`.`content_text`,`Mention`.`author_text`)
AGAINST ('+hannover +96' IN BOOLEAN MODE))) A
INNER JOIN Mention B USING (id)
WHERE LOCATE('hannover 96', title_text) > 0
OR LOCATE('hannover 96',content_text) > 0
OR LOCATE('hannover 96', author_text) > 0;
試してみる !!!
最初のクエリが遅い理由を説明できますが、2番目のクエリが速い理由は説明できません。 :)
私の理論では、ft_min_Word_len
はシステムで「2」より長い(デフォルトは4)ため、「Word」「96」は実際にはフルテキストインデックスになりません...全表スキャン、または少なくとも、インデックスに「ハノーバー」を含むすべての行を見つけ、最終的な基準に一致しない行を破棄する必要があります。残念ながら、フルテキストインデックスを含むクエリに関しては、EXPLAIN SELECTは通常ほど価値がありません。明らかに、そのインデックスが試行されるかどうかを通知するだけです。
これらを見てください:
https://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html
https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_ft_min_Word_len
そうでない場合は、クエリをベンチマークするときにSELECT SQL_NO_CACHE ...
を使用することをお勧めします。または、一見すると高速なクエリキャッシュからの応答を取得している可能性があります。