私はMySQL 5.5を使用しています。サブクエリを使用するクエリ(全文)があります。パフォーマンスと私がページネーションを使用しているという事実を助けるために、私は結果の数を制限するためにLIMITを使用しています。数を最適化してクエリを選択
SELECT *
FROM (
SELECT id, type, type_id, content, MATCH(content) AGAINST('john') as relevance, IFNULL (parent_type, UUID()) as parent_type, IFNULL(parent_id, UUID()) as parent_id
FROM search_index
WHERE MATCH(content) AGAINST('john*' IN BOOLEAN MODE) GROUP BY parent_type, parent_id) as search
GROUP BY search.type, search.type_id DESC LIMIT 10;
これに加えて、各検索クエリでは、可能な結果の合計数(例:50000)を返送する必要があります。カウントを取得するには、私は使用しています:
SELECT COUNT(*) FROM(
SELECT *
FROM (
SELECT id, type, type_id, content, MATCH(content) AGAINST('john') as relevance, IFNULL (parent_type, UUID()) as parent_type, IFNULL(parent_id, UUID()) as parent_id
FROM search_index
WHERE MATCH(content) AGAINST('john*' IN BOOLEAN MODE) GROUP BY parent_type, parent_id) as search
GROUP BY search.type, search.type_id) as count;
これは私にやや不安です。ここではカウントクエリのために説明します:
search_index
がcontent
上のフルテキストインデックスです。 search_index_no_ft
は、content
およびid
を除くすべての列のインデックスです。 id
に主キーがあります。
これを行うより良い方法がありますか、おそらくこれを最適化する方法ですか?または、2つのクエリ(カウントと検索)を1に結合する方法はありますか?
実際に一致する数が正確に必要ですか?グーグルが見積もりだけを表示する理由がある必要があります... – piotrm
ほとんどの場合、たとえば、ユーザーリストのフィルタリングや検索などの場合に有効なページ番号を生成するには、正確な一致数が必要です。データの量が非常に多く、ユーザーがとにかくすべてを通過することはないので、私は見積もりに満足しています。だから、私のユースケースには完全一致が必要です。 – F21
一部のユーザーは、もしあなたがそれをやらせるならば、それらをすべてやってみようとするでしょう。制限に基づくページネーションのウェブサイトで最も高いオフセットを乱用するのは、一般的なDOS攻撃です。 – piotrm