Mysql left join with nested select慢,如何优化
Posted
技术标签:
【中文标题】Mysql left join with nested select慢,如何优化【英文标题】:Mysql left join with nested select slow, how to optimize 【发布时间】:2021-08-01 00:47:50 【问题描述】:我有一个执行速度很慢的 LEFT JOIN mysql 查询,我正在寻找改进。 我有一个表“VM”列出了“VmId”(+ 一些其他数据)和另一个表“VM_Status”列出了 VM 的状态(上/下),每一行都有一个“inputDate”。
表 VM 为 7.000 行,表 VM_Status 为 76.000 行
我需要选择 7.000 VM 的最新状态
我的查询如下,执行需要 25 秒:
SELECT
VM.*,
`VM_Status`.`Status` AS `Status`
FROM VM
left join (
select
*
from
`VM_Status` `s1`
where
(
`s1`.`InputDate` = (
select
max(`s2`.`InputDate`)
from
`VM_Status` `s2`
where
(`s1`.`VmId` = `s2`.`VmId`)
)
)
) `VM_Status` on(
(
`VM_Status`.`VmId` = `WORKLOAD`.`VmId`
)
)
我怎样才能更快地做到这一点?
【问题讨论】:
查看添加的标签。 【参考方案1】:您可以使用窗口函数。Window Functions in MySQL
MySQL 支持窗口函数,对于查询中的每一行,使用与该行相关的行执行计算。
在您的情况下,您可以使用带有 order by 子句的 RANK() 或 DENSE_RANK() 函数,并在窗口内获取该 MAX(避免慢速连接)。 见:RANK
类似的东西:
select
*
from (
SELECT
VM.*,
`VM_Status`.`Status` AS `Status`,
RANK() OVER(PARTITION BY `VM_Status`.`VmId` ORDER BY `VM_Status`.`InputDate` DESC) rank
FROM VM left join `VM_Status`
ON `VM_Status`.`VmId` = `VM`.`VmId`
) `last_status`
WHERE
rank = 1
【讨论】:
谢谢,我不知道 RANK()。但是我在 5.7 版上,我的东西 RANK() 仅在 8 上可用。我尝试了一个替代方案,但它从 1 级到 78.000 级返回了 78.000 行......我错过了什么? select * from ( SELECT VM.VmId, VM_Status.Status
AS Status
, @curRank := @curRank + 1 AS Rank FROM (SELECT @curRank := 0) r, VM 离开加入 VM_Status ON VM_Status.VmId = VM .VmId ORDER BY VM_Status.InputDate DESC ) last_status
ORDER BY Rank以上是关于Mysql left join with nested select慢,如何优化的主要内容,如果未能解决你的问题,请参考以下文章