在 JOIN 中重写慢速 SQL(子)查询
Posted
技术标签:
【中文标题】在 JOIN 中重写慢速 SQL(子)查询【英文标题】:Rewriting a slow SQL (sub) query in JOIN 【发布时间】:2015-05-29 07:31:51 【问题描述】:所以我有大量慢速 SQL 查询,我已将其缩小为慢速子查询,因此我想将其重写为 JOIN。但我被卡住了......(由于MAX
和GROUP BY
)
SELECT *
FROM local.advice AS aa
LEFT JOIN webdb.account AS oa ON oa.shortname = aa.shortname
WHERE aa.aa_id = ANY (SELECT MAX(dup.aa_id)
FROM local.advice AS dup
GROUP BY dup.shortname)
AND oa.cat LIKE '111'
ORDER BY aa.ram, aa.cpu DESC
LIMIT 0, 30
【问题讨论】:
WHERE 子句中的 oa.cat LIKE '111' 使 LEFT JOIN 作为常规内部连接执行。如果您真的想要左连接,请将该条件移至 ON 子句。 感谢您提供信息,但您能否将其写为对我问题的回答,以便更清楚?提前致谢! 但这不是您问题的答案,这是另一个问题。你知道你想要左连接还是内连接? local.advice 表的左连接,因为我需要具有唯一短名称的每条记录的最大 ID 的记录。然后我用这个表加入 webdb 以获取有关该短名称的更多信息。 【参考方案1】:这是您的查询的不同版本,其中子查询使用连接子句进行转换
select * from local.advice aa
JOIN webdb.account oa ON oa.shortname = aa.shortname
join(
select max(aa_id) as aa_id,shortname from local.advice
group by shortname
)x on x.aa_id = aa.aa_id
where
oa.cat = '111'
order by aa.ram, aa.cpu DESC
limit 0,30
此外,如果尚未添加索引,您可能需要应用索引
alter table local.advice add index shortname_idx(shortname);
alter table webdb.account add index cat_shortname_idx(cat,shortname);
alter table local.advice add index ram_idx(ram);
alter table local.advice add index cpu_idx(cpu);
我假设aa_id
是主键所以没有添加索引
确保在应用索引之前备份表
【讨论】:
别开玩笑了,这个疯了!将我的查询搜索速度提高了 26 倍! 现在需要多少时间?您也可以使用explain select..
查看查询运行状况。
从13秒到0.5秒,记住1个表包含300万条记录,其他10K
INDEX(ram, cpu)
会比INDEX(ram)
好; INDEX(cpu)
没用。如果aa_id
不是PRIMARY KEY of
advice, then it needs
INDEX(aa_id)` 和INDEX(short_name, aa_id)
。以上是关于在 JOIN 中重写慢速 SQL(子)查询的主要内容,如果未能解决你的问题,请参考以下文章
优化 SQL:如何重写此查询以提高性能? (使用子查询,摆脱 GROUP BY?)