优化MySQL查询

优化MySQL查询,mysql,query-optimization,Mysql,Query Optimization,我有一个MySQL数据库,有3个表 Keywords id, keyword, projects_id Year results_id*, jan, feb, mar, ..., nov, dec Results id, keywords_id*, country, user star = foreign key 我需要找到项目1中存在的任何关键字以及项目2、3和4中存在的关键字每年生成的总数量,这些关键字按国家和用户分组 这就是我目前所拥有的 SELECT SUM(y.january

我有一个MySQL数据库,有3个表

Keywords
id, keyword, projects_id

Year
results_id*, jan, feb, mar, ..., nov, dec

Results
id, keywords_id*, country, user

star = foreign key
我需要找到项目1中存在的任何关键字以及项目2、3和4中存在的关键字每年生成的总数量,这些关键字按国家和用户分组

这就是我目前所拥有的

SELECT SUM(y.january + 
           y.february +
           ...
           y.december) AS 'sum',
       r.country , r.user
       FROM results r, year y           
       WHERE y.results_id = r.id 
             AND keywords_id IN(
                                   SELECT DISTINCT k.id
                                   FROM keywords k 
                                   JOIN keywords kk ON k.keyword = kk.keyword
                                   WHERE k.projects_id = 1 
                                   AND kk.projects_id IN (2,3,4)
                                   )
       GROUP BY country, user;
我的逻辑是:

  • 查找属于项目1的所有关键字的ID,这些关键字也位于项目2、3、4中,并带有联接
  • 然后查找包含任何关键字id的关键字id条目的任何结果
  • 最后,将年份表中的所有卷相加,并按国家和用户分组
  • 我尝试了第一步的子查询(括号内的子查询),它返回1700多个关键字

    但是当我在30分钟后尝试整个关键字时,我没有得到任何结果

    如何重写查询以加快速度,或者如果我做错了什么


    提前多谢

    以下是我的写作方法。第一个查询通过project1关键字的限定符获取所有4个project1、2、3和4中必须存在的所有关键字,并将它们连接到其他的project2、3和4中。如果你想要一个项目1和2,3或4的任何最低限度,我会稍微改变它

    从那以后,只有加入到结果和年份表中。现在,帮助优化。关键字表应该在(id,projects\u id)上有索引。结果表应该有一个索引(关键字_id,country,user)——组中需要帮助的国家和用户

    select STRAIGHT_JOIN
          r.country,
          r.user,
          SUM( y.january + y.february + y.march
             + y.april   + y.may      + y.june
             + y.july    + y.august   + y.september
             + y.october + y.november + y.december ) as AllMonths
       from 
          ( SELECT k.id
               FROM keywords k
                  JOIN keywords k2 on k.id = k2.id AND k2.project_id = 2
                  JOIN keywords k3 on k.id = k3.id AND k3.project_id = 3
                  JOIN keywords k4 on k.id = k4.id AND k4.project_id = 4
               where 
                  k.project_id = 1 ) KeywordsInAll             
             JOIN results r
                ON KeywordsInAll.ID = r.keywords_id
                JOIN `year` y
                   ON r.id = y.results_id
       group by 
          r.country,
          r.user
    
    我将内部查询更改为至少从项目1开始使用关键字。。。如果项目1只有15个关键字,那么查询10000个关键字是没有意义的(夸大了,但只是示例)

    根据你发表的评论,我只想将预查询更改为与你的几乎完全相同,但保持在第一位并保留“直接连接”


    你能澄清一下吗。。。项目1中的关键字必须在所有其他项目中(即:关键字“test”也在项目2、3和4中)。而且不只是在其中任何一个(2或3或4)中发现。两个不同的查询。它们可以位于任何项目或任何其他项目上。因此,如果项目1有关键字“test”,查询将返回每月值的总和,如果“test”至少出现在一个以上的项目(2、3或4)@jon,我修改了答案。。。我会保留相似的关键字。太好了,就这样。我必须更改子查询中的ON子句来比较k.keyword=k2.keyword,因为所有ID都不同。但它现在起作用了。谢谢。
          ( SELECT DISTINCT k.id
               FROM keywords k
                  JOIN keywords k2 on k.id = k2.id 
                   AND k2.project_id IN (2, 3, 4 )
               where 
                  k.project_id = 1 ) KeywordsInAll