SQL-查询优化思路(行为表 t1 与业绩表 t2 关联):

语句实例(行为表 t1 与业绩表 t2 关联):

with t as (
	select 行为id , 
    	t1.行为时间 ,
        t2.用户id , 
        t2.业绩时间 ,
    	row_number() over(partition by t1.用户id order by t1.行为时间 desc) as rnk
    from 行为表 t1 
    join 业绩表 t2 on t1.用户id = t2.用户id and t1.行为时间 < t2.业绩时间
)

select t.行为id , t.行为时间 ,t.用户id, t.业绩时间 from t where t.rnk = 1

1、索引的优化

创建合适的索引
1-1、对 行为表 和 业绩表 中的 用户id 列创建索引,以提高 JOIN 操作的效率。

1-2、对 行为时间 和 业绩时间 列创建索引,以优化条件过滤和排序

1-3、如果查询中经常包含其他筛选条件(如 t1.行为时间 < t2.业绩时间),可以考虑使用复合索引,如 (用户id, 行为时间) 和 (用户id, 业绩时间)。

2、减少数据量

限制扫描范围
在 行为时间 和 业绩时间 之前进行过滤时,如果可以在 JOIN 前减少数据量,将大大提高性能。

SELECT t1.行为id, t1.行为时间, t2.用户id, t2.业绩时间
FROM 行为表 t1
JOIN 业绩表 t2
  ON t1.用户id = t2.用户id
 AND t1.行为时间 < t2.业绩时间
WHERE t2.业绩时间 > '2024-01-01';

3、减少冗余计算

3-1、避免不必要的列
在查询中只选择必要的列,避免返回不需要的列,尤其是在使用 SELECT * 时,会增加不必要的开销。
3-2、减少子查询
减少不必要的嵌套子查询或重复计算,可以通过 WITH 子句(CTE)或者窗口函数来减少计算量。

4、使用窗口函数

利用 ROW_NUMBER()、RANK() 等窗口函数可以高效地为每个用户排序并筛选出所需的数据。特别是结合 PARTITION BYORDER BY,可以减少复杂的聚合操作。

5、分区表

如果数据量非常大,可以考虑对表进行 分区(如按日期或用户 ID 分区),这样在执行查询时只需要扫描相关的分区,减少了全表扫描的开销。

6、批量操作

减少单次操作的数据量
如果你处理的数据量非常大,建议分批处理数据。通过将查询分成多个小批次执行,减少单次查询的负载,避免内存压力过大。

7、避免使用过多的 DISTINCT

如果查询结果不要求绝对去重,尽量避免使用 DISTINCTDISTINCT 需要额外的排序步骤,会增加计算开销。

8、使用合适的 JOIN 类型

根据业务逻辑,选择合适的 JOIN 类型。避免使用不必要的 LEFT JOIN 或者 FULL JOIN

9、分析 SQL 执行计划

使用 EXPLAIN 分析 SQL 执行计划:
通过 EXPLAIN 查看数据库如何执行查询。你可以看到是否有全表扫描、是否使用了索引、关联操作的顺序等。根据这些信息,进一步调整查询。

EXPLAIN 
SELECT t1.行为id, t1.行为时间,t2.用户id, t2.业绩时间
FROM 行为表 t1
JOIN 业绩表 t2
  ON t1.用户id = t2.用户id
 AND t1.行为时间 < t2.业绩时间;

10、并行查询

如果数据库支持并行查询(如 PostgreSQL 或 Oracle 等),可以利用多核处理器加快大数据量查询的执行时间

总结:

1、创建合适的索引,尤其是对于 用户id、行为时间 和 业绩时间 列进行单列或复合索引优化。
2、在 JOIN 之前减少数据量,通过过滤条件限制行为表中的数据行。
3、使用窗口函数优化排序和分组,避免过多的嵌套查询。
4、分析执行计划,调整索引、过滤条件及 JOIN 顺序,减少全表扫描。

posted on   cloud_wh  阅读(23)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
历史上的今天:
2022-09-22 Maven-基础
点击右上角即可分享
微信分享提示