0

ライブラリの検索ボックスの自動提案をコーディングしていますが、非常に遅いです。オンライン ツールや最適化を手伝ってくれる人はいますか?

 SELECT *,
       grbc_books.id book_id
FROM   grbc_books
       LEFT JOIN grbc_series
              ON grbc_books.series_id = grbc_series.id
       JOIN grbc_collections
         ON grbc_books.collection_id = grbc_collections.id
       LEFT JOIN grbc_places
              ON grbc_books.place_id = grbc_places.id
       RIGHT JOIN grbc_books_subjects
               ON grbc_books_subjects.book_id = grbc_books.id
       LEFT JOIN grbc_subjects
              ON grbc_books_subjects.subject_id = grbc_subjects.id
       RIGHT JOIN grbc_books_authors
               ON grbc_books_authors.book_id = grbc_books.id
       LEFT JOIN grbc_authors
              ON grbc_books_authors.author_id = grbc_authors.id
                 AND ( ( title LIKE "%yea%" )
                        OR ( subtitle LIKE "%yea%" )
                        OR ( series LIKE "%yea%" )
                        OR ( `subject` LIKE "%yea%" )
                        OR ( `first` LIKE "%yea%" )
                        OR ( `last` LIKE "%yea%" )
                        OR ( place LIKE "%yea%" ) )
GROUP  BY `title`,
          subtitle
ORDER  BY title
LIMIT  10;  

前もって感謝します。

4

5 に答える 5

1

ここでの主な減速はLIKE '%yea%'条件です。WHERE(また、最後の句ではなく、句に含めるべきではありませんLEFT JOIN ... ON...か?)このようなクエリの問題は、MySQLが必要な行を見つけるためにインデックスを使用できないことです。毎回フルスキャンを実行する必要があります。正しい解決策は、フルテキストインデックスを使用することです。

また、Oliが提案したように、を削除する*と役立つ場合があります。

于 2013-03-07T11:21:00.590 に答える
1

他の人が言ったように、おそらく LIKE がボトルネックです。私の提案は、いいねではなく MATCH AGAINST の使用を開始することです。 http://dev.mysql.com/doc/refman/5.5/en//fulltext-search.html

于 2013-03-07T11:26:18.147 に答える
1

「*」を本当に必要な列に置き換えてください...現在、すべてのテーブルのすべての列を取得しています!

于 2013-03-07T11:17:08.003 に答える
1

「%yea%」はインデックスを使用できないため非効率的ですが、「yea%」はインデックスを使用できるため、はるかに高速であることに注意してください。

テーブル内に関連付けられたデータがない可能性がある場合にのみ、テーブルを外部結合する必要があることに注意してください。あなたのデータ構造はわかりませんが、件名や作成者などのテーブルの場合、これはありそうにありません。

このクエリを書いていて、FULLTEXT を使用するように切り替えていない場合、次のようになると思います...

 SELECT DISTINCT b.title
               , b.subtitle
               , b.id book_id
   FROM grbc_books b
   JOIN grbc_collections c
     ON c.id = b.collection_id
   JOIN grbc_books_subjects bh
     ON bh.book_id = b.id
   JOIN grbc_subjects h
     ON h.id = bh.subject_id 
   JOIN grbc_books_authors ba  
     ON ba.book_id = b.id
   JOIN grbc_authors a
     ON a.id = ba.author_id 
   LEFT 
   JOIN grbc_series s
     ON s.id = b.series_id
    AND s.series  LIKE "%yea%" 
   LEFT 
   JOIN grbc_places p
     ON p.id = b.place_id 
    AND p.place   LIKE "%yea%" 
  WHERE b.title LIKE "%yea%" 
     OR b.subtitle LIKE "%yea%" 
     OR h.subject LIKE "%yea%" 
     OR a.first LIKE "%yea%" 
     OR a.last LIKE "%yea%" 
  ORDER  
     BY b.title
  LIMIT 10;  

...しかし、私の推測では、これがパフォーマンスに与える影響はごくわずかです。

于 2013-03-07T11:35:16.027 に答える
1

全文検索は、式からデータベースを削除することで「最適化」されます。オプションは次のとおりです。

  • ソル
  • エラスティック検索
  • スフィンクス

リレーショナル データベースは、全文検索に関しては非常に遅く、多くのことを行うことはできません。トラフィックが少ないことが予想され、速度が遅いことを許容できる場合は、テキスト フィールドにインデックスを追加してみてください。データ量に比例して INSERT ステートメントが遅くなります。

最後に、ステートメントの前に「EXPLAIN」を追加して、クエリのトラブルシューティングを行うことができます。

EXPLAIN SELECT *,
       grbc_books.id book_id
FROM   grbc_books
       LEFT JOIN grbc_series
              ON grbc_books.series_id = grbc_series.id
       JOIN grbc_collections
         ON grbc_books.collection_id = grbc_collections.id
       LEFT JOIN grbc_places
              ON grbc_books.place_id = grbc_places.id
       RIGHT JOIN grbc_books_subjects
               ON grbc_books_subjects.book_id = grbc_books.id
       LEFT JOIN grbc_subjects
              ON grbc_books_subjects.subject_id = grbc_subjects.id
       RIGHT JOIN grbc_books_authors
               ON grbc_books_authors.book_id = grbc_books.id
       LEFT JOIN grbc_authors
              ON grbc_books_authors.author_id = grbc_authors.id
                 AND ( ( title LIKE "%yea%" )
                        OR ( subtitle LIKE "%yea%" )
                        OR ( series LIKE "%yea%" )
                        OR ( `subject` LIKE "%yea%" )
                        OR ( `first` LIKE "%yea%" )
                        OR ( `last` LIKE "%yea%" )
                        OR ( place LIKE "%yea%" ) )
GROUP  BY `title`,
          subtitle
ORDER  BY title

データベース アプローチを使用する場合は、キャッシュを使用してクエリを繰り返さないようにすることを検討してください。

于 2013-03-07T11:35:27.610 に答える