Mysql SQL内部联接-性能改进

Mysql SQL内部联接-性能改进,mysql,sql,inner-join,correlated-subquery,sqlperformance,Mysql,Sql,Inner Join,Correlated Subquery,Sqlperformance,我有下面的SQL,但希望提高性能下面的选项2目前需要大约24秒 解释MySQL-使用下面答案中的示例 选项1-基本选择非常慢 更新 选项2-内部连接速度更快,但仍然太慢 我需要循环浏览流量记录,其中大约有900条,对于每个流量,请在messageinfo表中选择最新的相关流量,即具有该特定流量的最高traceid。上面的两个SQL示例都可以工作,但如果可能的话,我想看看是否可以提高选项2的性能。最终的结果应该是尽力而为的,并且只返回一个traceid,其中可以像内部连接一样找到相关的流记录。 有

我有下面的SQL,但希望提高性能下面的选项2目前需要大约24秒

解释MySQL-使用下面答案中的示例

选项1-基本选择非常慢

更新

选项2-内部连接速度更快,但仍然太慢

我需要循环浏览流量记录,其中大约有900条,对于每个流量,请在messageinfo表中选择最新的相关流量,即具有该特定流量的最高traceid。上面的两个SQL示例都可以工作,但如果可能的话,我想看看是否可以提高选项2的性能。最终的结果应该是尽力而为的,并且只返回一个traceid,其中可以像内部连接一样找到相关的流记录。 有人能建议一种更有效的方法吗?请记住,我希望在最终结果中返回两个表中的数据,如上面的示例所示

我还需要强调,我没有使用新的/更新的索引修改数据库的自由。因此,主要是在不修改数据库的情况下对SQL进行改进


也就是说,为将来的工作注意索引的改进仍然是有益的。

您可以使用SQL索引快速检索数据。你看不到索引,它们只是用来加速搜索/查询。下面是添加索引的语法

CREATE INDEX index_name
ON table_name (column1, column2, ...);

使用join重写查询的另一种方法是,将从属子查询部分移动到sub子句,并将其与主查询连接起来

select m.traceid, f.name, f.flowid, m.traceday, m.logtimestamp
from flow f
inner join messageinfo m on m.flowid = f.flowid
inner join (
    select flowid, max(traceid) traceid
    from messageinfo 
    group by flowid
) m1 on  m.flowid = m1.flowid and m.traceid = m1.traceid
order by f.name

还可以在flowid、traceid上添加复合索引,并为所有相关表显示CREATE TABLE语句,有关查询性能的问题始终是对给定查询的解释

也就是说,在我们等待必要的信息出现时,根据我的经验,不相关的子查询有时会优于相关的子查询,因此我会尝试以这种方式编写查询:

select m.traceid
     , f.name
     , f.flowid
     , m.traceday
     , m.logtimestamp
  from flow f
  join messageinfo m 
    on m.flowid = f.flowid
  Join
     ( select flowid
            , max(traceid) traceid 
         from messageinfo 
        Group
           By flowid
     ) x
    On x.flowid = f.flowid
   And x.traceid = m.traceid
 order 
    by f.name

您的查询很好-尽管您应该使用所有列的限定列名编写查询:


您需要messageinfoflowid、traceid上的索引。flowname、flowid上的索引也可能有帮助。

为什么不使用如下窗口函数: maxtraceid按traceid超额分配按traceid排序 来自messageinfo


在上面运行了几次查询,平均时间为11秒,是目前为止最快的。非常感谢@user1746582你能在你的问题中包括这个查询的解释计划吗?完成了,对你上面建议的查询运行解释,结果是pic片段。我有点惊讶解释没有说对派生表使用group by索引。FlowID索引的定义是什么?谢谢,我运行了您的查询并得到了以下结果:错误:“on子句”中的未知列“f.traceid”!很容易修复!!是的,我知道,我以为你会想澄清你的答案-pI再次运行了几次,并进行了更正,时间几乎与M Khalid Junaid的答案一致,即在一秒钟内,Khalid的速度稍快,但仅此而已。听起来像是一个群体最大问题:
select m.traceid, f.name, f.flowid, m.traceday, m.logtimestamp
from flow f
inner join messageinfo m on m.flowid = f.flowid
inner join (
    select flowid, max(traceid) traceid
    from messageinfo 
    group by flowid
) m1 on  m.flowid = m1.flowid and m.traceid = m1.traceid
order by f.name
select m.traceid
     , f.name
     , f.flowid
     , m.traceday
     , m.logtimestamp
  from flow f
  join messageinfo m 
    on m.flowid = f.flowid
  Join
     ( select flowid
            , max(traceid) traceid 
         from messageinfo 
        Group
           By flowid
     ) x
    On x.flowid = f.flowid
   And x.traceid = m.traceid
 order 
    by f.name
select m.traceid, f.name, f.flowid, m.traceday, m.logtimestamp
from flow f inner join
     messageinfo m 
     on m.flowid = f.flowid
where m.traceid = (select max(m2.traceid) from messageinfo m2 where m2.flowid = m.flowid)
order by f.name;