如何提高大型左外连接的性能?

时间:2016-12-19 15:06:32

标签: sql-server-2008 left-join

这些是我的表格:

Source_Artikelen - 列:文章 - 说明(1.438.171条记录)

Source_LevArt - 列:文章 - 制造商部件号(1.751.801记录)

...这就是我正在执行的查询

SELECT a.Artikel,a.Omschrijving, l.Artikel_Leverancier
  FROM Source_Artikelen AS a
       LEFT OUTER JOIN Source_LevArt AS l
    ON a.Artikel Like l.Artikel

此查询今晚运行了20多个小时,然后才手动取消。

那么我想做什么?

我想列出表格 Source_Artikelen 中的所有文章。然后我想看看 Source_LevArt 中是否有可用的制造商部件号。

  • 并非 Source_Artikelen 中的每篇文章都出现在 Source_LevArt
  • 有时在一篇文章的 Source_LevArt 中有多个制造商部件号

这就是为什么我需要使用 LEFT OUTER JOIN

我已经尝试了一些带索引的东西,但它并没有真正起作用。可能我做错了什么。

我真的可以使用一些帮助,因为这只是我写作的查询的开始。 我将不得不在以后添加2个其他(大)tabes作为左外连接...

更新2016年12月19日16:24: 嗨piet.t

SELECT TOP(20) a.Artikel,a.Omschrijving, l.Artikel_Leverancier 
  FROM Source_Artikelen AS a 
       LEFT JOIN Source_LevArt AS l 
    ON a.Artikel LIKE l.Artikel 

这需要9秒

SELECT TOP(20) a.Artikel,a.Omschrijving, l.Artikel_Leverancier 
  FROM Source_Artikelen AS a 
       LEFT JOIN Source_LevArt AS l 
    ON a.Artikel = l.Artikel 

这需要1秒钟!

我真的不知道因为我没有使用通配符而存在差异。

2 个答案:

答案 0 :(得分:0)

使用=而不是喜欢。

这两个索引应该为Select提供最佳性能。

CREATE INDEX idx ON Source_Artikelen(Artikel) INCLUDE(Omschrijving);

CREATE INDEX idx ON Source_LevArt(Artikel) INCLUDE(Artikel_Leverancier);

如果您实施它们并再次尝试SELECT,请上传一份执行计划吗?

答案 1 :(得分:0)

保罗怀特在这里介绍了这一点:Dynamic Seeks and Hidden Implicit Conversions

即使在完全匹配的情况下使用也倾向于进行动态搜索...这意味着在执行时知道要搜索的列,而不是在编译时...

下面是如何。,以下示例中的表的派生列。

  

[Expr1005] =标量运算符(CONVERT_IMPLICIT(varchar(12),[Aegon_X]。[Sales]。[Orders]。[custid] as [o]。[custid],0)),
  [Expr1006] =标量运算符( LikeRangeStart (CONVERT_IMPLICIT(varchar(12),[Aegon_X]。[Sales]。[Orders]。[custid] as [o]。[custid],0)) ),
  [Expr1007] =标量运算符( LikeRangeEnd (CONVERT_IMPLICIT(varchar(12),[Aegon_X]。[Sales]。[Orders]。[custid] as [o]。[custid],0)) ),
   [Expr1008] =标量运算符( LikeRangeInfo (CONVERT_IMPLICIT(varchar(12),[Aegon_X]。[Sales]。[Orders]。[custid] as [o]。[custid],0)) )

以下是保罗描述的内容,以及如何推导

  

上部工具提示显示Compute Scalar使用三个内部函数,LikeRangeStart,LikeRangeEnd和LikeRangeInfo。

     

前两个函数将范围描述为开放区间。第三个函数返回一组以整数编码的标志,这些标志在内部用于定义存储引擎的某些搜索属性。较低的工具提示显示了由LikeRangeStart和LikeRangeEnd的结果描述的开放区间的搜索,以及残差谓词'LIKE @Like'的应用。

总而言之,使用类似SQL的动态搜索在编译时派生搜索属性。

以下示例显示了不同的计划

使用like:
我真的不知道因为我没有使用通配符而存在差异。

select top 10* from sales.orders o
join
sales.customers c
on c.custid like o.custid

<强>计划:
enter image description here

现在使用完全匹配时..

 select top 10* from sales.orders o
    join
    sales.customers c
    on c.custid =o.custid   

enter image description here

您可以看到合并加入计划