如何在MSSQL中高效查询各公司每日的前/后一日价格?
优化MSSQL前后行价格查询的高效方案
嘿,你的这个查询不仅性能拉胯,其实还存在逻辑错误——它会把不同CompanyCode的行混在一起计算前后值,这显然不符合你“各companyCode对应的前一日价格与后一日价格”的需求!而且用全局自增的rownum做自关联,数据量一大就会触发大量的表扫描和关联操作,速度慢是必然的。
高效且逻辑正确的解决方案
在MSSQL里,专门有窗口函数LAG()和LEAD()来搞定这种“取同一分组内前后行数据”的需求,性能比你原来的自关联方案高太多了,而且逻辑完全准确:
SELECT p.CompanyCode, p.Date, -- 取同一公司的前一日价格 LAG(p.Price) OVER (PARTITION BY p.CompanyCode ORDER BY p.Date) AS PreviousValue, p.Price AS CurrentValue, -- 取同一公司的后一日价格 LEAD(p.Price) OVER (PARTITION BY p.CompanyCode ORDER BY p.Date) AS NextValue FROM Table1 p
关键优化点说明
PARTITION BY p.CompanyCode:确保我们只在同一个公司的范围内计算前后值,解决了原查询跨公司的逻辑错误。ORDER BY p.Date:保证按日期顺序取前一日和后一日的数据,符合业务需求。LAG()/LEAD()是MSSQL原生支持的窗口函数,执行计划会直接在一次扫描中完成前后值计算,避免了原方案中多次自关联的开销。
进一步提升性能:添加覆盖索引
要让这个查询跑得更快,建议给Table1创建一个覆盖索引,让数据库可以直接从索引中获取所有需要的数据,不需要回表查找:
CREATE NONCLUSTERED INDEX IX_Table1_CompanyCode_Date_Price ON Table1 (CompanyCode, Date) INCLUDE (Price);
这个索引的作用是:
- 按
CompanyCode分组、Date排序存储数据,避免查询时的额外排序操作。 INCLUDE (Price)让索引包含了查询需要的Price字段,彻底消除回表开销。
内容的提问来源于stack exchange,提问作者lind rev
相关产品推荐
相关产品推荐

