2010-12-13 39 views
0

没有任何人有一个想法,为什么这个连接操作未终止:SQL Server 2005 - 加入不会终止 - 速度问题?

SELECT * FROM 
(SELECT LOWER([Computer Name]) AS 'cname' FROM table1) 
AS export, 
(SELECT AssetID AS 'CCID', Hostname AS 'cname' FROM table2 WHERE LastVersionFlag=1) 
AS known 

WHERE export.cname = LEFT(known.cname, LEN(export.cname)); 

,我想解决的问题是:

  • 目录一栏“CNAME”载:“PC1”
  • 表2列“主机名”包含:“pc1.domain.com”
  • 表2还包含列“CCID”:123123

作为查询的结果,我需要从table1接收每个“cname”的CCID。

编辑:

查询正在运行>15分钟现在和不产生输出,也不终止。

  • 表1包含有关100.000rows
  • 表2包含200.000rows

任何想法如何加快查询?

EDIT2:

指数都穿上表1 CNAME和表2 CNAME

任务的时间表是这样的:http://i55.tinypic.com/1z3o0t4.png

回答

1

这是你在找什么,一个基本的加入?

SELECT known.CCID, export.[Computer Name] AS cname 
FROM 
table1 AS export 
INNER JOIN table2 AS known ON LOWER(export.[Computer Name]) = LOWER(LEFT(known.cname, LEN(export.[Computer Name]))) 
WHERE LastVersionFlag=1 

编辑: 下面是加快查询的一些建议:

首先,在连接字符串的操作是非常昂贵的。如果强制对联接进行不区分大小写的排序,您可以避免调用lower()。

例如...ON known.cname = export.[Computed Column] collate SQL_Latin1_General_Cp437_CI_AS_KI_WI

你最理想的做法是创建对表2的一个持久化计算列只包含使用公式从加入LEFT(known.cname, LEN(export.[Computer Name])),那么你可以把计算列的索引和表1的CNAME列中的CNAME。一旦完成,你的连接将是一个简单的平等,而不是一个严格操纵的比较。这将允许查询引擎制定更优化的计划。

+0

没错。据我可以看到您的查询执行与我的操作相同的操作,也不会终止... – 2010-12-13 07:37:45

+0

我可以问一下“不终止”是什么意思吗? – Laramie 2010-12-13 08:02:30

+0

相应地更新了标题/说明。 – 2010-12-13 08:04:09

1

我的猜测是你的查询不能执行,因为数据的大小。

它需要生成100.000 * 200.000行的Cartesian product,然后应用WHERE条件。

如果列的排序规则设置为不区分大小写(由数据库和服务器排序规则默认设置),则SQL Server比较不区分大小写。

要加快连接操作,请在table1 [Computer Name]和table2.Hostname上添加(唯一的?)索引。

修改您的查询

SELECT known.CCID, export.[Computer Name] AS cname 
FROM table1 AS export 
INNER JOIN table2 AS known 
    ON known.Hostname LIKE export.[Computer Name] + '%' 
    AND LastVersionFlag=1 

如果所有的主机名使用点CNAME符号,使用 '%'。

+0

感谢您的输入,我相应地调整了我的查询。然而它需要~20分钟的处理并返回一个空的结果集。我没有解释这一点,因为这两个表内有匹配... – 2010-12-13 09:34:10

1

只是旁注:默认情况下SQL Server工作在不区分大小写的模式(如果你没有做任何改变),所以你不必关心正常情况下的大写/小写。 使用像LOWER这样的函数可以防止使用索引。

为了加速最后的WHERE,你可以用LIKE来重写它,它将利用相关列上的索引(如果有的话)。这将是类似的(如在devio的答案):

known.cname LIKE (export.cname + '%') 
1

将所有建议汇集在一起​​会给你以下查询。
通过适当的索引和您提到的记录数量,不需要几分钟即可返回结果。

SELECT cname = t1.[Computer Name] 
     , CCID = k.AssetID 
     , Hostname = k.cname 
FROM table1 t1 
     INNER JOIN known k ON k.Hostname LIKE t1.[Computer Name] + '%' 
WHERE k.LastVersionFlag = 1   
+0

感谢您的输入,我相应地调整了我的查询。然而它需要~20分钟的处理并返回一个空的结果集。我没有解释这一点,因为这两个表内有匹配... – 2010-12-13 09:34:27

+0

@Michael,你能告诉我们一个SHOWPLAN语句的输出吗? – 2010-12-13 10:21:40

+0

'SET SHOWPLAN_ALL ON' – 2010-12-13 10:22:43