开发者

SQL Server 2005 - Join does not terminate - Speed issue?

does anybody have an idea why this join 开发者_Go百科operation does not terminate:

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

The problem which I want to solve is:

  • Table1 column "cname" contains: "pc1"
  • Table2 column "hostname" contains: "pc1.domain.com"
  • Table2 also contains column "CCID": 123123

As result of the query I need to receive the CCID of each "cname" from table1.

EDIT:

The query is running for >15minutes now and produces no output, nor terminates.

  • Table1 contains about 100.000rows
  • Table2 contains about 200.000rows

Any ideas how to speed up the query?!

EDIT2:

Indices are put on Table1 cname and Table2 cname

The task schedule looks like this: http://i55.tinypic.com/1z3o0t4.png


Is this what you're looking for, a basic join?

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 

Edit: Here are some suggestions for speeding up the query:

Firstly, the string operation in the join are very costly. You can avoid having to call lower() if you force a case insensitive collation for the join.

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

Your best move would be to create a persisted computed column on table2 that just contains the cname using your formula from the join LEFT(known.cname, LEN(export.[Computer Name])) , then you can put an index on the computed column as well as the cname column of table1. Once done, your join will be a simple equality instead of a heavily manipulated comparison. This will allow the query engine to make a more optimized plan.


Just a side note: SQL Server is working in case insensitive mode by default (if you didn't do any changes), so you dont have to care about upper/lower-case normally. Using functions like LOWER prevents the usage of indexes.

And to speed up the last WHERE, you could rewrite it with a LIKE that will take advantage of an index on the involved columns (if you got one). That would be something like (as in devio's answer):

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


Bringing all suggestions together would give you following query.
With proper indexing and the number of records you mention, it shouldn't take minutes to return the results.

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        


My guess is your query does not perform because of the size of the data.

It needs to generate the Cartesian product of 100.000 * 200.000 rows, and then apply the WHERE conditions.

SQL Server comparison is case-insensitive if the column's collation is set to case-insensitive (defaulted by database and server collations).

To speed up the join operation, add (unique?) indexes on table1.[Computer Name] and table2.Hostname.

Modify your query to

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 

If all your hostnames use dotted cname notation, use '.%'.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜