如何优化需排除98K条记录的SELECT语句执行效率?
SQL查询优化方案
一、彻底解决手动复制的麻烦:用子查询直接关联
不用再手动导出、拼接98K条IdValue,直接把第一个查询作为子查询嵌入第二个查询,一步完成过滤:
修正后的NOT IN写法(注意规避NULL问题)
Select FName, MI, LName, Dateofpurchase from Table3 inner join Table4 on Table3.Id = Table4.id where PurchaseType = 'Holiday' and IdValue NOT IN ( -- 只查询需要的IdValue,减少数据处理 Select IdValue from Table1 -- 修正原SQL的关联语法错误,替换成实际的字段关联 Inner Join Table2 ON Table1.Table1Id = Table2.Table2Id WHERE IdName = 'Acquisition' )
注意:如果子查询返回的IdValue包含NULL,NOT IN会导致整个过滤条件失效,此时优先用下面的NOT EXISTS写法。
更安全高效的NOT EXISTS写法
Select FName, MI, LName, Dateofpurchase from Table3 inner join Table4 on Table3.Id = Table4.id where PurchaseType = 'Holiday' and NOT EXISTS ( SELECT 1 -- 用SELECT 1比SELECT字段更高效 from Table1 Inner Join Table2 ON Table1.Table1Id = Table2.Table2Id WHERE IdName = 'Acquisition' -- 关联主查询的IdValue字段,确保过滤准确 AND Table1.IdValue = Table3.IdValue )
二、提升查询性能的核心优化
1. 加索引(最关键的优化手段)
给以下字段创建复合索引或单列索引,大幅缩短关联和过滤时间:
- Table1:
IdName、IdValue、关联Table2的字段(如Table1Id) - Table2:关联Table1的字段(如
Table2Id) - Table3:
PurchaseType、IdValue、关联Table4的Id字段 - Table4:关联Table3的
Id字段
2. 用LEFT JOIN替代NOT IN(大数据量下更稳定)
当排除数据量较大时,LEFT JOIN + IS NULL的性能通常优于NOT IN,且不会受NULL值影响:
-- 给表起别名,简化SQL并提升可读性 Select t3.FName, t3.MI, t3.LName, t3.Dateofpurchase from Table3 t3 inner join Table4 t4 on t3.Id = t4.id -- 左连接排除列表 left join ( Select IdValue from Table1 t1 Inner Join Table2 t2 ON t1.Table1Id = t2.Table2Id WHERE t1.IdName = 'Acquisition' ) exclude on t3.IdValue = exclude.IdValue where t3.PurchaseType = 'Holiday' -- 只保留不在排除列表里的数据 and exclude.IdValue IS NULL
三、其他细节修正
- 原Query One的关联条件
Inner Join Table2 ON Table1Id.Table2Id是语法错误,必须修正为Table1.xxx = Table2.xxx的字段等式,否则子查询无法正常执行。 - 子查询只保留需要的
IdValue字段,不要查询IDName、IDCreatedby这类无关字段,减少数据处理量。
内容的提问来源于stack exchange,提问作者DDLearn
相关产品推荐
相关产品推荐

