我可以优化这个MySQL查询吗?

时间:2014-04-04 22:37:45

标签: mysql join query-optimization

我的SQL是

SELECT authors.*, COUNT(*) FROM authors
    INNER JOIN resources_authors ON authors.author_id=resources_authors.author_id
WHERE
    resource_id IN
        (SELECT resource_id FROM resources_authors WHERE author_id = '1313')
    AND authors.author_id != '1313'
 GROUP BY authors.author_id`

我在查询中的所有字段都有索引,但我仍然得到Using temporary; Using Filesort

id  select_type         table             type            possible_keys                         key      key_len   ref                rows   Extra
1   PRIMARY             authors           ALL             PRIMARY                               NULL        NULL   NULL               16025  Using where; Using temporary; Using filesort
1   PRIMARY             resources_authors ref             author_id                             author_id      4   authors.author_id      3  Using where
2   DEPENDENT SUBQUERY  resources_authors unique_subquery resource_id,author_id,resource_id_2   resource_id  156   func,const             1  Using index; Using where

如何改进查询或表格结构以加快查询速度?

如果您想要试验,那么这里有一个SQL小提琴:http://sqlfiddle.com/#!2/96d57/2/0

1 个答案:

答案 0 :(得分:1)

我会通过“PreQuery”以不同的方式处理它。获取所有具有共同资源计数的作者的列表给另一位作者,但不要将原始作者包括在最终列表中。确定这些作者后,获取他们的姓名/联系信息和公共资源的总数,但不要获得共同的SPECIFIC资源。这将是一个稍微不同的查询。

现在,查询。为了帮助优化查询,我会有两个索引 一个就在(author_id) 另一个组合(resource_id,author_id) 你已经拥有。

现在解释内部查询。首先执行该部分,您可以看到执行计划将使用索引。这里的意图是,查询从资源作者开始,但只关心一个特定的作者(where子句),这将使这个结果集非常短。这是立即加入资源作者表,但只是基于相同的RESOURCE和作者不是主要的(来自where子句)只给你那些OTHER作者。通过添加COUNT(),我们现在确定每个相应商品有多少共享资源,按作者分组,每个作者返回一个条目。最后取出“PreQuery”结果集(所有已经过资格预审的记录),然后加入作者。获取详细信息并计算()并完成。

SELECT 
      A.*,
      PreQuery.CommonResources
   from 
      ( SELECT 
              ra2.author_id,
              COUNT(*) as CommonResources
           FROM 
              resources_authors ra1
                 JOIN resources_authors ra2
                    ON ra1.resource_id = ra2.resource_id
                    AND NOT ra1.author_id = ra2.author_id
           WHERE 
              ra1.author_id = 1313 
           GROUP BY
              ra2.author_id ) PreQuery
      JOIN authors A
         ON PreQuery.author_id = A.author_id