You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

合并同结构issues表后关联items表的慢查询优化求助

优化百万级数据的合并关联查询

你的查询之所以加载无响应,核心问题是先全表合并两个百万级的issues表,再做关联和过滤,这会导致临时表数据量巨大,而且没有利用索引优化。下面一步步帮你分析并给出优化方案:

原SQL的核心问题

  • 先合并后过滤:SELECT * FROM issues UNION SELECT * FROM old_issues会先扫描两个完整的大表,生成一个包含百万级数据的临时表,这一步的IO和内存开销极大。
  • RIGHT JOIN 被WHERE条件转为INNER JOIN:你的WHERE子句里加了new_issues.issuedate < '2018-01-01',这会过滤掉所有new_issues为NULL的记录,等同于用了INNER JOIN,RIGHT JOIN的逻辑完全没有意义。
  • 缺少合适的索引:如果没有针对过滤和关联字段的索引,全表扫描会让查询速度慢到难以接受。

优化方案

1. 先过滤再合并,缩小临时表规模

对每个issues表单独过滤issuedate < '2018-01-01',再合并。如果不需要去重,用UNION ALL比UNION快很多——因为UNION会额外做去重校验,完全是不必要的性能损耗。

2. 先筛选目标items数据,再关联

先把items中符合location='DEP' AND ccode='ARACD'的数据筛选出来,再和过滤后的issues数据关联,大幅减少关联的数据量。

3. 建立必要的索引

给issues和old_issues表添加联合索引:

CREATE INDEX idx_issues_itemno_issuedate ON issues(itemno, issuedate);
CREATE INDEX idx_oldissues_itemno_issuedate ON old_issues(itemno, issuedate);

给items表添加联合索引:

CREATE INDEX idx_items_itemno_loc_ccode ON items(itemnumber, location, ccode);

优化后的SQL

SELECT i.itemnumber AS itemno, filtered_issues.issuedate
FROM (
    -- 先过滤两个issues表,再合并
    SELECT itemno, issuedate FROM issues WHERE issuedate < '2018-01-01'
    UNION ALL -- 如果需要去重就换成UNION,否则用ALL更高效
    SELECT itemno, issuedate FROM old_issues WHERE issuedate < '2018-01-01'
) AS filtered_issues
INNER JOIN (
    -- 先筛选符合条件的items数据
    SELECT itemnumber FROM items WHERE location = 'DEP' AND ccode = 'ARACD'
) AS i ON i.itemnumber = filtered_issues.itemno;

针对你的测试数据的预期结果

结合你提供的表数据,运行优化后的SQL会得到:

itemnoissuedate
2002017-12-21
2002017-12-20

解释:

  • items中符合条件的是itemno 200、300
  • 过滤后的issues数据只有old_issues里的200(两条)、400、500,但400的location不是DEP,500的ccode不是ARACD,所以最终只返回200的两条记录。

内容的提问来源于stack exchange,提问作者BoostBoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:16:13