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

MySQL Join与子查询性能对比:获取符合条件的用户首单日期

MySQL Join与子查询性能对比:选最优方案获取用户首单日期

我们需要从tb_order和tb_user表中,获取满足**订单状态为1(已完成)或2(已取消)**的用户首单日期,输出格式为order_id、user_id、user_1st_order_date,时间字段均为Unix时间戳。当前有两种实现方案,需选出性能最优的用于每日更新Tableau Online数据源。


Option 1: JOIN方案

原写法存在逻辑漏洞,昨日突然失效返回用户最新订单时间,给ox.create_time加上Min()函数后可得到正确的首单时间。

Select
    o.id as 'order_id',
    u.id as 'user_id',
    Min(x.create_time) as 'user_1st_order_date' -- 外层需聚合确保取首单时间
from
    tb_order o
    left join tb_user u on o.user_id = u.id
    /* 此处约有10个关联查询 */

    left join
    (
        select
            ux.id,
            Min(ox.create_time) as create_time -- 子查询内必须用Min()获取用户最早订单时间
        from
            tb_user ux
            left join tb_order ox on ox.user_id = ux.id
        where
            ( ox.order_status = 1 or ox.order_status = 2 ) 
            /* 订单状态为已完成或已取消 */
        group by
            ux.id
    ) x on x.id = u.id 

where
    o.create_time != 0
    and
    ( o.order_status = 1 or o.order_status = 2 )

group by
    o.id 

原思路是通过group by ux.id聚合用户订单,但未加聚合函数时,MySQL会随机返回一条匹配的create_time,导致结果错误。


Option 2: 子查询方案

Select 
    o.id as 'order_id', 
    u.id as 'user_id', 
    (
        select
            ox.create_time
        from
            tb_order ox
        where
            (ox.order_status = 1 or ox.order_status = 2) 
            and
            ox.user_id = u.id 
        order by
            ox.id asc 
        limit 1
    ) as 'user_1st_order_date'
from
    tb_order o
    left join tb_user u on o.user_id = u.id 
    /* 此处约有10个关联查询 */

where
    o.create_time != 0
    and
    ( o.order_status = 1 or o.order_status = 2 )

group by
    o.id 

性能对比与最优选择

  1. 优化后的Option 1:

    • 子查询先批量预计算所有符合条件用户的首单时间,再与主查询关联,属于一次性批量处理模式。如果给tb_order创建复合索引idx_user_status_create(user_id, order_status, create_time),子查询的聚合效率会大幅提升,主查询关联时也能快速匹配。
    • 优势:仅需一次预计算,主查询关联成本低,适合数据量较大的每日更新场景。
  2. Option 2:

    • 属于关联子查询,主查询每返回一行,就会触发一次子查询去获取对应用户的首单时间。如果主查询结果集行数较多(比如上万条以上),重复执行子查询的开销会非常高,性能急剧下降。
    • 劣势:小数据集下表现尚可,但大数据量场景下性能拉胯,不适合每日更新的Tableau数据源。

结论:优先选用优化后的Option 1方案,同时配合上述复合索引进一步提升性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:50:32