SQL 内部联接 - 性能改进
SQL inner join - performance improvement
我有以下 SQL 但希望提高性能(下面的选项 2 目前大约需要 24 秒)。
EXPLAIN MySQL - 在下面的答案中使用示例
选项 1 - 基本 select(非常慢)
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 个),对于每个流 select 消息信息中的相关流 table 是最新的,即具有最高的 traceid对于那个特定的流程。上面的两个 SQL 示例都有效,但我想看看我是否可以在可能的情况下提高选项 2 的性能。最终结果应该是尽力而为,只有 return 一个可以找到相关流记录的 traceid(如内部连接)。
谁能建议一种更高效的方法?请记住,我想在最终结果中 return 来自两个 table 的数据(如上例所示)。
我还需要强调,我没有修改带有 new/updated 索引的数据库的自由。所以主要是在不修改数据库的情况下寻找 SQL 的改进。
也就是说,注意到任何索引改进对于未来的工作仍然是有益的。
您可以使用 SQL 索引来快速检索您的数据。你看不到索引,它们只是用来加速 searches/queries。以下是添加索引的语法。
CREATE INDEX index_name
ON table_name (column1, column2, ...);
另一种使用连接重写查询的方法,将依赖的子查询部分移至子句并将其与主查询连接。
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) 上添加复合索引
以及所有相关表的 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
您的查询很好——尽管您应该使用限定的列名编写它所有列:
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;
您需要 messageinfo(flowid, traceid)
上的索引。 flow(name, flowid)
上的索引也可能有帮助。
为什么不使用像这样的 window 函数:
max(traceid) over(partition by traceid order by traceid)
来自消息信息
?
我有以下 SQL 但希望提高性能(下面的选项 2 目前大约需要 24 秒)。
EXPLAIN MySQL - 在下面的答案中使用示例
选项 1 - 基本 select(非常慢)
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 个),对于每个流 select 消息信息中的相关流 table 是最新的,即具有最高的 traceid对于那个特定的流程。上面的两个 SQL 示例都有效,但我想看看我是否可以在可能的情况下提高选项 2 的性能。最终结果应该是尽力而为,只有 return 一个可以找到相关流记录的 traceid(如内部连接)。 谁能建议一种更高效的方法?请记住,我想在最终结果中 return 来自两个 table 的数据(如上例所示)。
我还需要强调,我没有修改带有 new/updated 索引的数据库的自由。所以主要是在不修改数据库的情况下寻找 SQL 的改进。
也就是说,注意到任何索引改进对于未来的工作仍然是有益的。
您可以使用 SQL 索引来快速检索您的数据。你看不到索引,它们只是用来加速 searches/queries。以下是添加索引的语法。
CREATE INDEX index_name
ON table_name (column1, column2, ...);
另一种使用连接重写查询的方法,将依赖的子查询部分移至子句并将其与主查询连接。
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) 上添加复合索引
以及所有相关表的 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
您的查询很好——尽管您应该使用限定的列名编写它所有列:
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;
您需要 messageinfo(flowid, traceid)
上的索引。 flow(name, flowid)
上的索引也可能有帮助。
为什么不使用像这样的 window 函数: max(traceid) over(partition by traceid order by traceid) 来自消息信息
?