web-dev-qa-db-ja.com

ORDER BYを使用して全文検索を高速に行う方法は?

1億行を超えるテーブルの別の列でorder byを使用するときに、単純なFULLTEXT一致を高速化しようとしています。基本は、2つの列にフルテキストを含む1つのテーブルであり、データベースを検索したいのですが、プライマリ(最小/最新)または人気の順に並べています。別のインデックス付けされた列での注文によるFULLTEXTを高速にすることは可能ですか? SQL Fiddle以下のスキーマとすべてのクエリの説明:

参照 SQL Fiddle#1

これまでのところ非常に高速なのは、別のテーブルと結合での検索列の非正規化ですが、必要がない場合は別のテーブルを使用したくありません。 SQL Fiddle下(非正規化クエリの最後)):

参照 SQL Fiddle#2

3
JJJ

ここでの最初の問題はあなたが制御できないものです。それは何ですか ???

FULLTEXTインデックスに対するクエリオプティマイザーの反応。どうして ?

(今度は、スクロールワードを使ったSTAR WARSムービーの開始を想像してみてください...)

ずっと前に、FULLTEXTインデックスがMySQL Query Optimizerによる他のインデックスの使用を無効にすることを発見しました

提案

MATCH ...AGAINSTがキーのみを収集するようにクエリをリファクタリングする

例#1

SELECT a.id FROM a 
WHERE
MATCH (`search1`,`search2`) AGAINST ('aaaa' IN BOOLEAN MODE)
ORDER BY a.id DESC
LIMIT 5;

のようなものになるはずです

SELECT N.id FROM
(SELECT id FROM a WHERE
MATCH (`search1`,`search2`) AGAINST ('aaaa' IN BOOLEAN MODE)) M
INNER JOIN a N USING (id)
ORDER BY N.id DESC LIMIT 5;

例2

SELECT a.id,a.popularity FROM a 
WHERE
MATCH (`search1`,`search2`) AGAINST ('aaaa' IN BOOLEAN MODE)
ORDER BY a.popularity DESC
LIMIT 5;

のようなものになるはずです

SELECT N.id,N.popularity FROM
(SELECT id FROM a WHERE
MATCH (`search1`,`search2`) AGAINST ('aaaa' IN BOOLEAN MODE)) M
INNER JOIN a N USING (id)
ORDER BY N.popularity DESC LIMIT 5;

結論

主なアイデア:MATCH ...AGAINSTを使用してキーを収集し、ソーステーブルに結合する

4
RolandoMySQLDBA