使用条件连接优化SQL查询

时间:2017-02-17 20:55:25

标签: sql-server join query-optimization

我需要运行一个查询来比较两个表并返回不在第二个表中的记录。棘手的部分是两个表之间的链接是有条件的。我有多个来源进入表2,然后进入表1。我尝试过使用连接,但这并不比我下面的更快。这些表中有大约5万条记录。此查询大约需要1.5分钟才能完成。我希望大约几秒钟。 Table1和Table2已经在这些字段上有索引。 DB在兼容级别SQL2008上运行。

此查询大约需要1.5分钟:

select *
from Table1 t1 
where not exists (select * 
                  from Table2 t2
                  where t2.seedID = case t2.SeedSource when 'SeedSource1' then t1.SeedSource1
                                                       when 'SeedSource2' then t1.SeedSource2
                                                       when 'SeedSource3' then t1.SeedSource3
                                                       when 'SeedSource4' then t1.SeedSource4 
                                                       when 'SeedSource5' then t1.SeedSource5 end)

此查询需要五分钟:

select d.*
from Tabel1 t1 left join
     Table2 t2 on t2.seedID = case t2.SeedSource when 'SeedSource1' then t1.SeedSource1 
                                                 when 'SeedSource2' then t1.SeedSource2
                                                 when 'SeedSource3' then t1.SeedSource3
                                                 when 'SeedSource4' then t1.SeedSource4
                                                 when 'SeedSource5' then t1.SeedSource5  end
where t2.seedID is NULL

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

阅读完您的要求后,您的查询就可以了。 (最佳做法是使用Not Exists代替Not INLeft Join

您可以进行一些小优化:

  • WHERE子句中使用not exists (select 1 ...代替not exists (select * ...,当您可以选择常量时,无需选择所有列。 (表现更好)

<强>参考

答案 1 :(得分:1)

实际上它们不是同一个查询,因为左连接会在多个匹配项上返回多行

不存在是更好的方法

我希望SeedSource,SeedSource1-5和seedID被编入索引

select *
from Table1 t1 
where not exists ( select * 
                   from Table2 t2
                   where t2.seedID = t1.SeedSource1 
                   and   t2.SeedSource = 'SeedSource1' 
                   union all  
                   select * 
                   from Table2 t2
                   where t2.seedID = t1.SeedSource2 
                   and   t2.SeedSource = 'SeedSource2'
                   //...
                 )

也许

left join Table2 t2
  on ( t2.seedID = t1.SeedSource1 and t2.SeedSource = 'SeedSource1' )
  or ( t2.seedID = t1.SeedSource2 and t2.SeedSource = 'SeedSource2' )
  // ...

答案 2 :(得分:0)

也许:

SELECT t1.* FROM table1 t1 LEFT JOIN table2 t2 on t1.seedID = t2.seedID 
WHERE t2.seedID is NULL AND t1.SeedSource IN ('SeedSource1','SeedSource2','SeedSource3','SeedSource4','SeedSource5')