2016-08-02 115 views
1

我有以下查询SQL服务器优化问题

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 
           ) 

TableA大约有记录200000

TableB有大约50000记录

当我运行此查询它花费太大约2分钟时间。

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

我该怎么做才能优化这个查询?

+3

请张贴执行计划以XML,表架构有一些样本数据 – TheGameiswar

+0

你有'可乐<> 0 2个AND和AND CONCAT' – vercelli

+1

是的cols号码?你确定连接它们吗? 'select select concat(a,b) from(select 11 as a,2 as b union all select 1,12)t 其中concat(a,b)='112' – Serg

回答

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) 

我不知道很多关于你的表架构或索引,但我知道有一点可以肯定的是,表达CONCAT(ColA,ColB)不是可优化搜索。写相同的查询有点不同,如果在列ColAColB的列上存在索引,则会更快。

+0

理论上,您的查询可能会带来结果不正确。在你的情况下,'CONCAT(ColA,ColB)'将等于'CONCAT(ColB,ColA)',不是吗? –

0

CONCAT将排除任何索引在您的列在两个表中寻找。

如果您的查询的主要目的是找到所有在TableA而非TableB中的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 
    ) 

注:这将导致比当前的查询但它很难不实际的执行计划和现有的表结构和索引

0

使用set operation评论更好的执行计划:

SELECT ColA, ColB FROM TableA WHERE ColA <> 0 
EXCEPT 
SELECT ColA, ColB FROM TableB WHERE ColB <> 0 

DISTINCT需要的原因EXCEPT无论如何这样做。

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 
0

正如一些海报所指出的那样,你将需要使用CONCAT而不是在可乐COLB进行查询的独立,以获得正确的数据试试。

如果这是一个足够重要的查询值得自己的索引,或CONCAT(ColA,ColB)是常用的数据。您可以考虑为CONCAT(ColA,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)