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

MySQL左连接带条件查询耗时28秒,去条件仅1秒的问题排查与优化

MySQL LEFT JOIN 查询性能问题分析与优化方案

嘿,这个问题我在日常调试MySQL查询时碰到过好多次,咱们来拆解下问题根源和优化方案~

问题根源

你把左表(regist_queue)的筛选条件和右表的额外筛选条件都塞进了LEFT JOIN的ON子句里,这是导致查询变慢的核心原因:

  • 对于LEFT JOIN来说,ON子句的作用是定义关联规则,而非筛选主表数据。如果把左表的LocationId、QueueDate这类筛选条件放在ON里,MySQL会先尝试把左表全量数据和右表做关联,之后再过滤符合条件的记录,这会产生大量不必要的关联计算,耗时自然飙升。
  • 另外,你用date(rq.QueueDate)、date(ap.dAppDate)这种函数包裹字段的写法,会导致字段上的索引失效,数据库只能做全表扫描,进一步拖慢查询速度。

优化修改方案

1. 拆分筛选条件的位置

把左表的筛选条件移到WHERE子句中,让MySQL先过滤出左表的有效数据,再进行关联操作,大幅减少后续关联的数据量;右表的额外筛选条件可以保留在ON里(确保LEFT JOIN的特性:左表符合条件的记录全部保留,右表只匹配符合条件的记录)。

2. 避免函数包裹字段,改用范围查询

把date(字段) = 日期的写法改成范围区间查询,这样可以利用字段上的索引,避免全表扫描:

  • 原写法:date(rq.QueueDate) = CURRENT_DATE()
  • 优化后:rq.QueueDate >= CURRENT_DATE() AND rq.QueueDate < DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY)

3. 添加针对性索引

给关联字段和筛选字段创建复合索引,让MySQL能快速定位数据:

  • 给regist_queue创建:INDEX idx_rq_token_loc_date (token_number, LocationId, QueueDate)
  • 给appoint创建:INDEX idx_ap_ticket_loc_date_pat (daily_ticket_no, LocationId, dAppDate, iPatID)
  • 给patient创建:INDEX idx_pr_patid (IPatID)

修改后的查询语句示例

SELECT * 
FROM regist_queue rq
LEFT JOIN appoint ap 
    ON rq.token_number = ap.daily_ticket_no 
    AND ap.LocationId = 15800 
    AND ap.dAppDate >= CURRENT_DATE() 
    AND ap.dAppDate < DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY)
LEFT JOIN patient pr 
    ON ap.iPatID = pr.IPatID
-- 这里补充你剩下的JOIN语句
WHERE rq.LocationId = 15800 
  AND rq.QueueDate >= CURRENT_DATE() 
  AND rq.QueueDate < DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY);

4. 验证执行计划

修改后可以用EXPLAIN命令查看执行计划,确认是否用到了预期的索引,避免出现type: ALL(全表扫描)的情况。

内容的提问来源于stack exchange,提问作者Ammar Muhi ud din

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:35:06