SQL内部联接 - 性能改进

时间:2018-06-11 06:16:13

标签: mysql sql inner-join correlated-subquery sqlperformance

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

EXPLAIN MySQL - 使用以下enter image description here

中的答案中的示例

选项1 - 基本选择(非常慢)

select f.name, f.flowid, m.traceid, m.traceday, m.logtimestamp
from flow f, messageinfo m 
where traceid = (select max(traceid) from messageinfo where flowid = f.flowid)

更新

选项2 - 内连接(更快但仍然太慢)

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

我需要遍历流记录(大约有900个),并且对于每个流,选择messageinfo表中最新的相关流,即具有该特定流的最高traceid。上面的两个SQL示例都有效,但是如果可能的话,我想看看是否可以提高Option 2的性能。最终结果应该是尽力而为,并且只返回可以找到相关流记录的traceid(如内连接)。 任何人都可以建议更高效的方式吗?请记住,我想在最终结果中返回两个表中的数据(如上例所示)。

我还需要强调,我没有自由使用新的/更新的索引修改数据库。所以主要是在没有DB修改的情况下寻找SQL的改进。

尽管如此,未来工作的任何指数改进仍然是有益的。

5 个答案:

答案 0 :(得分:0)

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

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)

上添加复合索引

答案 1 :(得分:0)

除了所有相关表的SHOW CREATE TABLE语句外,有关查询性能的问题始终是给定查询的EXPLAIN。

那就是说,在等待显示必要信息的同时,根据我的经验,不相关的子查询有时可能胜过相关的子查询,所以我很想尝试以这种方式编写查询:

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

答案 2 :(得分:0)

您的查询很好 - 尽管您应该使用所有列的合格列名来编写

messageinfo(flowid, traceid)

您需要flow(name, flowid)上的索引。 cqlsh xx:x:x:x xxxx got below error: Connection error: ('Unable to connect to any servers', {'xx:x:x:x': ConnectionShutdown('Connection to xx:x:x:x was closed',) } ) 上的索引也可能有所帮助。

答案 3 :(得分:0)

为什么不使用像以下一样的窗口函数: max(traceid)over(traceid按traceid分区) 来自messageinfo

答案 4 :(得分:-1)

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

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