SQL server优化问题

SQL server优化问题,sql,sql-server-2012,query-optimization,Sql,Sql Server 2012,Query Optimization,我有以下疑问 SELECT DISTINCT ColA,ColB AS S from TableA where ColA <> 0 AND CONCAT(ColA,ColB) NOT IN ( SELECT DISTINCT CONCAT(ColA,ColB) from TableB WHERE ColB

我有以下疑问

SELECT DISTINCT ColA,ColB AS S 
   from TableA  
   where ColA <> 0        
   AND CONCAT(ColA,ColB) NOT IN (
                                   SELECT DISTINCT CONCAT(ColA,ColB) from TableB
                                   WHERE ColB <> 0
                                )
表A有大约200000条记录和

表B有大约50000条记录

当我运行此查询时,大约需要2分钟的时间

如何优化此查询以减少执行时间

我应该如何优化此查询

试试这个

SELECT DISTINCT A.ColA, A.ColB AS S 
from TableA  A
where A.ColA <> 0 
AND NOT EXISTS (SELECT 1
                from TableB B
                WHERE B.ColB <> 0
                AND A.ColA= B.ColA
                AND A.ColB = B.ColB)

我对您的表模式或索引了解不多,但有一件事我可以肯定,CONCATColA,ColB表达式不是Sargable。以稍微不同的方式编写相同的查询,如果ColA和ColB列上有in索引,则会更快

CONCAT将排除对两个表中的列进行任何索引查找

如果查询的主要目的是查找表A中而不在表B中的所有ColA、ColB组合,则可以尝试以下方法

SELECT DISTINCT ColA,ColB AS S 
FROM TableA  
WHERE ColA <> 0
AND NOT EXISTS(
    SELECT TOP 1 * FROM TableB
    WHERE TableB.ColA = TableA.ColA
    AND TableB.ColB = TableA.ColB 
    AND TableB.ColB <> 0
   )
注意:这将产生比当前查询更好的执行计划,但是如果没有实际的执行计划和现有的表结构和索引,则很难进行评论使用:


没有明确的必要原因,但仍要执行此操作。

您可以尝试使用此查询

SELECT DISTINCT ColA,ColB AS S
FROM TableA LEFT OUTER JOIN TableB 
    ON TableA.ColA = TableB.ColA
      and TableA.ColB = TableB.ColB
WHERE TableA.ColA <> 0
    and TableB.ColB <> 0
    and TableB.ColB is null

正如一些海报所指出的,为了获得正确的数据,您需要使用CONCAT而不是单独查询ColA和ColB

如果这是一个非常重要的查询,值得使用它自己的索引或CONCATColA,那么ColB是常用的数据。您可以考虑为CONCATColA、ColB创建一个计算列,并在该计算列上创建一个索引

    SELECT DISTINCT 
    A.ColA, A.ColB
    FROM TableA A 
    LEFT JOIN TableB B 
    ON B.CONCAT(ColA,ColB) = A.CONCAT(ColA,ColB)
    WHERE A.ColA <> 0
    and B.ColB <> 0
    and B.ColB is null
我还很幸运地使用CTE进行筛选,然后在最后进行任何计算,以充分利用表中当前的索引

    WITH FilteredA as (
    select ColA, ColB
    from tableA 
    WHERE ColA <> 0 ), 

    FilteredB as (
    select ColA, ColB
    from tableB 
    WHERE ColB <> 0 ) 

    SELECT DISTINCT FilteredA.*
    from FilteredA 
    LEFT JOIN FilteredB ON FilteredA.ColA = FilteredB.ColB
    AND FilteredA.ColB = FilteredB.ColB
    WHERE FilteredA.CONCAT(ColA,ColB) = FilteredB.CONCAT(ColA,ColB)

请将执行计划发布为xml、表模式和一些示例数据。您在ColA 0和CONCATAre cols编号中有2个AND?你确定要连接它们吗?从select 11中选择concat a,b作为a,2作为b union all select 1,12 t,其中concat a,b='112'理论上,您的查询可能会带来不正确的结果。在你的情况下,可乐等于可乐,可乐,不是吗?
    WITH FilteredA as (
    select ColA, ColB
    from tableA 
    WHERE ColA <> 0 ), 

    FilteredB as (
    select ColA, ColB
    from tableB 
    WHERE ColB <> 0 ) 

    SELECT DISTINCT FilteredA.*
    from FilteredA 
    LEFT JOIN FilteredB ON FilteredA.ColA = FilteredB.ColB
    AND FilteredA.ColB = FilteredB.ColB
    WHERE FilteredA.CONCAT(ColA,ColB) = FilteredB.CONCAT(ColA,ColB)