SSMS多表关联查询性能异常缓慢,请求排查代码是否存在严重低效问题
你的SQL查询确实存在几个可能导致低效的问题,以下是具体分析和优化建议:
1. 不必要的SELECT *导致数据冗余
你的CTE里用了select *,会把car和car_and_engine表的所有字段都加载到临时结果集中。如果这两张表字段多、数据量大,会额外占用大量内存和IO资源,拖慢后续的关联操作。永远只查询你实际需要的字段,不要用*。
2. 关联字段缺少索引
car.car_type_x和car_and_engine.car_type_y这两个关联字段如果没有创建索引,数据库在执行join时会做全表扫描。对于数据量较大的表,全表扫描的开销极高。建议给这两个字段分别创建非聚集索引:
CREATE NONCLUSTERED INDEX IX_car_car_type_x ON TRANSPORT.dbo.car (car_type_x); CREATE NONCLUSTERED INDEX IX_car_and_engine_car_type_y ON TRANSPORT.dbo.car_and_engine (car_type_y);
3. 临时表缺少索引
你创建的临时表#horsepower_by_engine_type后续被三次用来关联,但如果没有给engine_type字段加索引,每次join都会对临时表做全表扫描。即使临时表数据量不大,三次扫描的累积开销也会很明显。创建临时表后立即添加索引:
select engine_type, AVG(horsepower) into #horsepower_by_engine_type from TRANSPORT.dbo.engine group by engine_type; CREATE NONCLUSTERED INDEX IX_temp_engine_type ON #horsepower_by_engine_type (engine_type); go
4. 不必要的LEFT JOIN
检查业务逻辑是否真的需要LEFT JOIN:如果car表中没有对应car_and_engine记录的车型不需要保留,换成INNER JOIN可以大幅缩小结果集,提升查询速度。
优化后的示例代码
-- 带索引的临时表 select engine_type, AVG(horsepower) into #horsepower_by_engine_type from TRANSPORT.dbo.engine group by engine_type; CREATE NONCLUSTERED INDEX IX_temp_engine_type ON #horsepower_by_engine_type (engine_type); go -- 只查询需要的字段,用INNER JOIN(如果业务允许) with temp as( select c.car_type_x, ce.engine_type_1, ce.engine_type_2, ce.engine_type_3 -- 这里只保留后续需要用到的字段 from TRANSPORT.dbo.car c inner join TRANSPORT.dbo.car_and_engine ce on ce.car_type_y = c.car_type_x ) select t.*, e1.[AVG(horsepower)] as avg_horsepower_1, e2.[AVG(horsepower)] as avg_horsepower_2, e3.[AVG(horsepower)] as avg_horsepower_3 from temp t left join #horsepower_by_engine_type e1 on t.engine_type_1 = e1.engine_type left join #horsepower_by_engine_type e2 on t.engine_type_2 = e2.engine_type left join #horsepower_by_engine_type e3 on t.engine_type_3 = e3.engine_type;
内容的提问来源于stack exchange,提问作者Howard
相关产品推荐
相关产品推荐

