表之间有两列连接,一列等于,另一列不等于

时间:2017-09-03 23:52:53

标签: sql sql-server performance equals

SQL Server 2012中有两个表都有6.4 million个记录。让我们说A和B.我必须根据两列连接两个表。让我们说A.C1 = B.C1A.C2 <> B.C2.两个C1 and C2都是nvarchar列。 表B没有聚集索引。我的查询如下所示:

select B.C1...A.C12, A.C2...A.C5
from A
inner join B on A.C1 = B.C1
where A.C2 <> B.C2

这需要超过16分钟,最多30分钟。它在B上执行全表扫描,作为B中的其他列。当超过30分钟时,查询超时。能告诉我这个查询的最佳方法是什么。

4 个答案:

答案 0 :(得分:1)

由于表B上没有聚集索引,因此这是一个很好的机会。 C1为第1键,C2为第2键。您还需要在A上使用类似的(C1,C2)非聚集索引。根据A中的列,您可能希望也可能不希望它成为覆盖索引...

就可读性而言,我将代码格式化为......

SELECT
    b.C1,
    ...
    b.C12,
    a.C2,
    ...
    a.C5
FROM
    A a
    JOIN B b
        ON a.C1 = b.C1
        AND a.C2 <> b.C2;

答案 1 :(得分:0)

尝试:

select B.C1...A.C12, A.C2...A.C5
from A
inner join B on A.C1 = B.C1 

减去

select B.C1...A.C12, A.C2...A.C5
from A
inner join B on A.C2 = B.C2

答案 2 :(得分:0)

对您的查询没有疑问: 为了在每个查询中获得更好的性能:

  1. 数据库规范化,包括Blob数据类型。
  2. 数据库始终为indexes
  3. 确保您拥有High Speed机器规格。
  4. 数据库Software功能。

答案 3 :(得分:0)

您可以使用索引视图。它们提高了查询性能。

   --Set the options to support indexed views.  
SET NUMERIC_ROUNDABORT OFF;  
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT,  
    QUOTED_IDENTIFIER, ANSI_NULLS ON;  
GO  
--Create view with schemabinding.  
IF OBJECT_ID ('A.B', 'view') IS NOT NULL  
DROP VIEW A.B;  
GO  
CREATE VIEW A.B 
WITH SCHEMABINDING  
AS  
    SELECT  B.C1...A.C12, A.C2...A.C5
    FROM A 
    inner join B on A.C1 = B.C1 
    Where A.C2 <> B.C2;  
GO  
--Create an index on the view.  
CREATE UNIQUE CLUSTERED INDEX IDX_V1   
    ON A.B (B.C1, A.C12);  
GO  

有关详细信息,请查看此create indexed views