我有三张桌子:
我使用此查询来获取一位作者,该作者的书籍在畅销书列表中保留了最长的周数:
SELECT authors.full_name, COUNT(*) FROM authors
INNER JOIN books ON books.author LIKE CONCAT('%', authors.full_name, '%')
INNER JOIN list_items ON list_items.book_title = books.title
GROUP BY authors.full_name ORDER BY count(*) DESC LIMIT 1
此查询大约需要6分钟,而没有第二个JOIN的类似查询则需要不到一秒钟。如何优化我的查询?
的更新
EXPLAIN
就是这样:
table type possible_keys key key_len ref rows Extra
authors ALL <NULL> <NULL> <NULL> <NULL> 2555 Using temporary; Using filesort
list_items ALL book_name <NULL> <NULL> <NULL> 31040 Using join buffer
books eq_ref PRIMARY PRIMARY 767 list_items. 1 Using where
book_title
答案 0 :(得分:1)
我认为你不需要使用额外的subselect语句。我采用了你更快的语句并删除了内部的select语句。不知道这会影响执行时间,但它有点清洁,imho。
SELECT COUNT(*), authors.full_name
FROM list_items
INNER JOIN books ON books.title = list_items.title
INNER JOIN relations ON books.id = relations.book_id
INNER JOIN authors ON authors_id = relations.author_id
GROUP BY authors.full_name
ORDER BY COUNT(*);
答案 1 :(得分:0)
最终,我通过重组数据库方案解决了这个问题。
根问题在字段books.author
中可能包含多个作者名称,因此在初始查询中包含CONCAT。我添加了一个新表来应用多对多关系,其中authors.id
和books.id
已关联。
然后我使用了这个查询:
SELECT COUNT (*), items.full_name
FROM list_items
INNER JOIN
(SELECT books.title, authors.full_name
FROM books INNER JOIN relations ON books.ID = relations.book_id
INNER JOIN authors ON authors.ID = relations.author_id
) items ON items.title = list_items.book_title
GROUP BY items.full_name
ORDER BY COUNT (*) DESC;
执行时间降至0.4秒。