Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 需要特定的SQL查询优化帮助_Mysql_Sql_Query Optimization - Fatal编程技术网

Mysql 需要特定的SQL查询优化帮助

Mysql 需要特定的SQL查询优化帮助,mysql,sql,query-optimization,Mysql,Sql,Query Optimization,因此,我正在从事一个数据挖掘项目,在该项目中,我们将研究代码元素及其关系,以及随着时间的推移对这些内容的更改。我们想问的是一些关于相关元素改变频率的问题。我已将其设置为视图,但运行大约需要10分钟。我相信问题是我必须做大量的减法、串联和字符串比较来比较条目(对于我们的窗口大小),但我不知道解决这个问题的好方法。这个查询看起来像 select aw.same , rw.k , count(distint concat_ws(',', r1.id, r2.id)) as num

因此,我正在从事一个数据挖掘项目,在该项目中,我们将研究代码元素及其关系,以及随着时间的推移对这些内容的更改。我们想问的是一些关于相关元素改变频率的问题。我已将其设置为视图,但运行大约需要10分钟。我相信问题是我必须做大量的减法、串联和字符串比较来比较条目(对于我们的窗口大小),但我不知道解决这个问题的好方法。这个查询看起来像

select aw.same
     , rw.k
     , count(distint concat_ws(',', r1.id, r2.id)) as num  
  from deltamethoddeclaration dmd1
    join revision r1
      on r1.id=FKrevID 
    join methodinvocation mi
      on mi.FKcallerID = dmd1.FKMDID 
    join deltamethoddeclaration dmd2 
      on mi.FKcalleeID = dmd2.FKMDID
    join revision r2 
      on r2.id = dmd2.FKrevID
    join revisionwindow rw
    join authorwindow aw
  where (dmd1.FKrevID - dmd2.FKrevID) < rw.k
    and (dmd2.FKrevID - dmd1.FKrevID) < rw.k
    and case aw.same
          when 1 then
            r1.author = r2.author
          when 0 then
            r1.author <> r2.author
          else
            1=1
         end
  group by aw.same
         , rw.k
;
选择aw.same
,rw.k
,计数(distint concat_ws(',,r1.id,r2.id))为num
来自deltamethoddeclaration dmd1
加入修订版r1
在r1上。id=FKrevID
连接方法调用mi
在mi.FKcallerID=dmd1.FKMDID上
加入deltamethoddeclaration dmd2
在mi.FKcalleeID=dmd2.fkmid上
加入修订版r2
在r2.id=dmd2.FKrevID上
连接修订窗口rw
加入authorwindow aw
其中(dmd1.FKrevID-dmd2.FKrevID)
好的,所以revisionwindow存储我们感兴趣的修订窗口(10、20、50、100),authorwindow存储我们想要的作者类型(相同、不同和不在乎)。问题的一部分是,我们可能有相同的修订对与不同的元素匹配,所以我唯一能想到的就是丑陋的计数(distinct concat())问题。这将返回一个包含12行的表,每个作者和修订窗口组合一行。“num”下的条目是以指定方式相关的唯一修订对(在本例中,两个更改方法和一个方法调用另一个)。它工作得非常好,速度非常慢(运行时间约10分钟)。我基本上是在寻找任何建议或帮助,以便在不牺牲准确性的情况下使这项工作更好。

我怀疑这两个连接(
join-revisionwindow rw
)和(
join-authorwindow aw
)没有ON条件,但使用WHERE,导致了这一问题

这两个表有多少条记录?MySQL可能首先对这些进行交叉连接,然后才检查复杂的(WHERE)条件

但是请发布
解释的结果

--编辑--
哎呀,我错过了你上一段解释这两个表有4行和3行的内容

你能试试这个吗 (如果更换了混凝土 where子句已移动为JOIN ON…)

选择aw.same
,rw.k
,计数(distint r1.id,r2.id)为num
来自deltamethoddeclaration dmd1
加入修订版r1
在r1.id=dmd1.FKrevID上
连接方法调用mi
在mi.FKcallerID=dmd1.FKMDID上
加入deltamethoddeclaration dmd2
在mi.FKcalleeID=dmd2.fkmid上
加入修订版r2
在r2.id=dmd2.FKrevID上
连接修订窗口rw
关于(dmd1.FKrevID-dmd2.FKrevID)
  • 其中(dmd1.FKrevID-dmd2.FKrevID)
    此语句最具破坏性的是小于运算符
    ,是否有所有主键/外键的索引?每个表中有多少行?
    methodinvocation
    中有多少记录?所有键都被索引。methodinvocation表中大约有110K个条目。deltamethoddeclaration有120K个条目,修订版有14K@KyleP-是否有任何理由使用Case表达式而不是
    aw.same=1和r1.author=r2.author
    ?因为我也希望在aw.same不是1时得到结果,这些结果不应该询问作者是否相同。我一定是误解了你的问题。内特,谢谢你的评论。很明显,我以前没有做过类似的事情,所以你能给我一个更具体的指示,说明如何解决这个问题吗?由于它是减去两个关键点,我还可以使用第一个链接中讨论的范围技巧吗?或者你能给我一个例子说明在临时表中放入什么以及如何使用它吗?@Kyle:假设你可以使用预计算的索引,但在这种情况下不起作用,因为它们只能使用一个表中的常量和值(而不是自联接)。为创建临时表然后添加索引可能是一个不错的选择。@Kyle:不确定索引是否是您的主要问题,因为看起来您在扫描大多数行时没有太多选择性。这可能是一个完整的表扫描结果,无论你做什么。我会认真考虑使用不同的ID和相同的作者案例表达式预计算临时表。如果您能够预先聚合数据,那么查询可能会运行得非常快。然后查询带有修订和作者窗口内容的临时表。
    select aw.same
         , rw.k
         , count(distint r1.id, r2.id) as num  
      from deltamethoddeclaration dmd1
        join revision r1
          on r1.id = dmd1.FKrevID 
        join methodinvocation mi
          on mi.FKcallerID = dmd1.FKMDID 
        join deltamethoddeclaration dmd2 
          on mi.FKcalleeID = dmd2.FKMDID
        join revision r2 
          on r2.id = dmd2.FKrevID
        join revisionwindow rw
          on (dmd1.FKrevID - dmd2.FKrevID) < rw.k
             and (dmd2.FKrevID - dmd1.FKrevID) < rw.k
        join authorwindow aw
          on case aw.same
               when 1 then
                 r1.author = r2.author
               when 0 then
                 r1.author <> r2.author
               else
                 1=1
              end
      group by aw.same
             , rw.k
    ;