WITH base AS ( SELECT a.user_id, a.level, b.name, b.dept_id, a.supervisor_id, CASEWHEN a.supervisor_id =0THEN''ELSE b2.name ENDAS supervisor_name, CASEWHEN a.supervisor_id =0THEN0ELSE a2.level ENDAS supervisor_level FROM public.source_user_data a LEFTJOIN public.user_profile b ON b.user_id = a.user_id LEFTJOIN public.source_user_data a2 ON a2.user_id = a.supervisor_id LEFTJOIN public.user_profile b2 ON b2.user_id = a.supervisor_id ) SELECT*FROM base;
WITH base AS ( SELECT a.user_id, a.level, b.name, b.dept_id, a.supervisor_id, CASEWHEN a.supervisor_id =0THEN''ELSE b2.name ENDAS supervisor_name, CASEWHEN a.supervisor_id =0THEN0ELSE a2.level ENDAS supervisor_level FROM public.source_user_data a LEFTJOIN public.user_profile b ONdate(to_timestamp(b.update_time)) =current_date AND b.user_id = a.user_id LEFTJOIN public.source_user_data a2 ONdate(to_timestamp(a2.update_time)) =current_date AND a2.user_id = a.supervisor_id LEFTJOIN public.user_profile b2 ONdate(to_timestamp(b2.update_time)) =current_date AND b2.user_id = a.supervisor_id WHEREdate(to_timestamp(a.update_time)) =current_date ) SELECT*FROM base;
效果
数据量:300万 → 4000(降低约1000倍)
执行时间:3919ms → 190ms(**提升95%**)
内存占用:33G → 7.4G(**降低79%**)
2. 分页查询,减少展示
场景
用户排行榜接口,通常只展示前50名。
优化前(无分页)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
WITH sales_data AS ( SELECT user_id, SUM(sales_amount) AS total_sales FROM sales_daily WHERE brand_id ='B12345' AND sale_date BETWEEN'20240807'AND'20241104' GROUPBY user_id ), user_rank AS ( SELECT u.user_id, u.nick, s.total_sales FROM user_info u JOIN sales_data s ON u.user_id = s.user_id ) SELECT ur.*, p.profile_name, p.avatar FROM user_rank ur JOIN user_profile p ON ur.user_id = p.user_id ORDERBY ur.total_sales DESC -- 无 LIMIT,返回全部数据
优化后(添加分页)
1 2 3
... ORDERBY ur.total_sales DESC LIMIT 50OFFSET0;
效果
执行时间:13190ms → 2447ms(**提升81.4%**)
内存占用:基本持平
3. 内连接替代左连接
场景
用户与销售数据关联,业务要求用户必须有销售记录。
优化前(使用 LEFT JOIN)
1 2 3 4
... FROM user_info u LEFTJOIN sales_data s ON u.user_id = s.user_id ...
优化后(改用 INNER JOIN)
1 2 3 4
... FROM user_info u INNERJOIN sales_data s ON u.user_id = s.user_id ...