SQL Server 2005 - 加入不终止 - 速度问题?

时间:2010-12-13 07:20:56

标签: sql-server-2005 join

有没有人知道为什么这个连接操作不会终止:

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));

我想解决的问题是:

  • 表1列“cname”包含:“pc1”
  • 表2列“hostname”包含:“pc1.domain.com”
  • 表2还包含“CCID”栏:123123

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

编辑:

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

  • 表1包含约100.000rows
  • 表2包含约200,000个

任何想法如何加快查询速度?!

EDIT2:

指数放在Table1 cname和Table2 cname

任务时间表如下所示:http://i55.tinypic.com/1z3o0t4.png

4 个答案:

答案 0 :(得分: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()。

e.g。 ...ON known.cname = export.[Computed Column] collate SQL_Latin1_General_Cp437_CI_AS_KI_WI

你最好的举措是在table2上创建一个持久的计算列,它只使用你的联接LEFT(known.cname, LEN(export.[Computer Name]))中的公式包含cname,然后你可以在计算列和cname列上放置一个索引。表格1。完成后,您的联接将是一个简单的平等,而不是一个严重操纵的比较。这将允许查询引擎制定更优化的计划。

答案 1 :(得分:1)

我的猜测是,由于数据的大小,您的查询无法执行。

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

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

要加快连接操作,请在table1上添加(唯一?)索引。[计算机名]和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表示法,请使用'。%'。

答案 2 :(得分:1)

请注意:默认情况下,SQL Server正在使用不区分大小写的模式(如果您没有进行任何更改),因此您不必正常关注大写/小写。 使用LOWER等功能可以阻止索引的使用。

为了加快上一个WHERE,您可以使用LIKE重写它,它将利用所涉及列的索引(如果有的话)。这就像(在devio的答案中):

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

答案 3 :(得分: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