是否有任何在线工具或可以简化此MySQL SELECT查询的人?

时间:2013-03-07 11:13:29

标签: php mysql select

我正在为图书馆的搜索框编码自动提示,但速度非常慢。 是否有任何在线工具或任何愿意帮助我优化它的人?

 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;  

提前致谢。

5 个答案:

答案 0 :(得分:1)

将'*'替换为您真正需要的列...现在您正在获取所有表格的所有列!

答案 1 :(得分:1)

此处的主要减速将是LIKE '%yea%'条件。 (另外 - 它们不应该在WHERE子句中,而不是最后一个LEFT JOIN ... ON...子句吗?)这种查询的问题是MySQL不能使用任何索引来查找必要的行。它需要每次都进行全面扫描。正确的解决方案是使用fulltext index

此外,作为Oli suggested,删除*可能有所帮助。

答案 2 :(得分:1)

正如其他人所说,LIKE可能是你的瓶颈。我的建议是你开始使用MATCH AGAINST而不是喜欢。 http://dev.mysql.com/doc/refman/5.5/en//fulltext-search.html

答案 3 :(得分: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;  

......但我的猜测是,这只会对性能产生微小的影响。

答案 4 :(得分:1)

通过从等式中删除数据库来“优化”全文搜索。您的选择是:

  • Solr的
  • 弹性搜索
  • 斯芬克斯

关于全文搜索,关系数据库非常慢,你无法做很多事情。如果您希望流量较小而且可以接受缓慢,请尝试在文本字段中添加索引。它会使INSERT语句与数据量成比例地变慢。

最后,您可以在Statement:

之前添加“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

如果您决定继续使用数据库方法,请考虑缓存以不重复查询。