SQL Server查询的性能问题

时间:2011-06-01 14:11:13

标签: sql-server

这是我的疑问:

SELECT ID, [type], naam, adresl1, adresl2, tel, fax, email, contactpersoon
FROM
    ------------------------ START --------------------------
    (SELECT av.personID as [id], 'P' as [type], 
            av.firstname + ' ' + av.lastname as 'naam', 
            av.straat as 'adresl1',
            c.zipCode + ' ' + c.City as 'adresl2',
            av.phone as 'tel',
            '' as fax,
            av.Email as 'email',
            '' as 'website', '' as 'contactpersoon',
            coalesce(a1.aliasTitle,'') + '|' + coalesce(a1.aliasTitle2,'') + '|' + coalesce(1.aliasTitle3,'') + '|' + 
            coalesce(a2.aliasTitle,'') + '|' + coalesce(a2.aliasTitle2,'') + '|' + coalesce(a2.aliasTitle3,'') + '|' + 
            coalesce(f.FunctionTitle,'') + '|' + coalesce(r.Raad,'') + '|' + coalesce(rci.RedCrossInstitutionName,'') + '|' + 
            coalesce(av.firstname,'') + ' ' + coalesce(av.lastname,'') + '|' + 
            coalesce(av.lastname,'') + ' ' + coalesce(av.firstname,'') AS 'wie',
            coalesce(a1.aliasTitle,'') + '|' + coalesce(a1.aliasTitle2,'') + '|' + coalesce(a1.aliasTitle3,'') AS 'waar',
            coalesce(echelon.Street,'') + '|' + coalesce(echelon.zipcode,'') + '|' + 
            coalesce(echelon.City,'') + '|' + coalesce(echelon.RedCrossEntityName,'') AS 'waar_E'
    FROM RVW_vwAdresboekVrijwilligers av
    LEFT JOIN City c ON av.CityID = c.CityID
    LEFT JOIN AliasPerson ap ON av.PersonID = ap.PersonID
    LEFT JOIN Alias a1 ON ap.AliasID = a1.AliasID
    LEFT JOIN FunctionPerson fp ON av.PersonID = fp.PersonID
    LEFT JOIN 
         (SELECT RedCrossEntity.RedCrossEntityID, RedCrossEntity.RedCrossEntityName, 
                 RedCrossEntity.street, City.zipcode, City.city
          FROM RedCrossEntity
          LEFT JOIN City ON RedCrossEntity.CityID = City.CityID
         ) AS echelon ON echelon.RedCrossEntityID = fp.RedCrossEntityID
    LEFT JOIN [Function] f ON f.FunctionID = fp.FunctionID
    LEFT JOIN AliasFunction af ON af.FunctionID = f.FunctionID
    LEFT JOIN Alias a2 ON a2.AliasID = af.AliasID
    LEFT JOIN FunctionRaad fr ON fr.FunctionID = f.FunctionID
    LEFT JOIN Raad r ON r.RaadID = fr.RaadID
    LEFT JOIN RedCrossInstitution rci ON rci.RedCrossInstitutionID = fp.RedCrossInstitutionID
    WHERE 
        f.functionid IN (SELECT functionid FROM FunctionResponsibility 
                         WHERE ResponsibilityTypeId = 4)
------------------------- END -----------------------
 ) data     
WHERE 
     (wie LIKE '%jos%' OR waar LIKE '+++++'  )
ORDER BY 
     [type]

-START-和-END-之间的部分工作正常,并在大约3秒内执行。但是当我添加WHERE (wie LIKE '%jos%' OR waar LIKE '+++++' )时,运行需要30秒。

我也试过这个:

.......
LEFT JOIN RedCrossInstitution rci ON rci.RedCrossInstitutionID = fp.RedCrossInstitutionID   
WHERE 
     1=1 
     AND (a1.aliasTitle LIKE '%jos%'
        OR a1.aliasTitle2 LIKE '%jos%'
        OR a1.aliasTitle3 LIKE '%jos%'
        OR a1.aliasTitle LIKE '+++++'
        OR a1.aliasTitle2 LIKE '+++++'
        OR a1.aliasTitle3 LIKE '+++++'
        OR a2.aliasTitle LIKE '%jos%'
        OR a2.aliasTitle2 LIKE '%jos%'
        OR a2.aliasTitle3 LIKE '%jos%'
        OR f.FunctionTitle LIKE '%jos%'
        OR r.Raad LIKE '%jos%'
        OR rci.RedCrossInstitutionName LIKE '%jos%'
        OR (av.firstname + ' ' + av.lastname LIKE '%jos%')
        OR (av.lastname + ' ' + av.firstname LIKE '%jos%')
          )
      AND f.functionid IN (SELECT functionid FROM FunctionResponsibility 
                           WHERE ResponsibilityTypeId = 4)

但那甚至更慢。

有没有人看到加快这个速度的方法?

4 个答案:

答案 0 :(得分:3)

请删除 IN 并将其替换为如下所述的加入。通过这种方式,我们可以避免由于 IN

而发生的循环
SELECT ID, [type], naam, adresl1, adresl2, tel, fax, email, contactpersoon
        FROM(
    ------------------------ START --------------------------
            SELECT av.personID as [id], 'P' as [type], 
                av.firstname + ' ' + av.lastname as 'naam', 
                av.straat as 'adresl1',
                c.zipCode + ' ' + c.City as 'adresl2',
                av.phone as 'tel',
                '' as fax,
                av.Email as 'email',
                '' as 'website', '' as 'contactpersoon',
                coalesce(a1.aliasTitle,'') + '|' + coalesce(a1.aliasTitle2,'') + '|' + coalesce(a1.aliasTitle3,'') + '|' + 
                    coalesce(a2.aliasTitle,'') + '|' + coalesce(a2.aliasTitle2,'') + '|' + coalesce(a2.aliasTitle3,'') + '|' + 
                    coalesce(f.FunctionTitle,'') + '|' + coalesce(r.Raad,'') + '|' + coalesce(rci.RedCrossInstitutionName,'') + '|' + 
                    coalesce(av.firstname,'') + ' ' + coalesce(av.lastname,'') + '|' + 
                    coalesce(av.lastname,'') + ' ' + coalesce(av.firstname,'') AS 'wie',
                coalesce(a1.aliasTitle,'') + '|' + coalesce(a1.aliasTitle2,'') + '|' + coalesce(a1.aliasTitle3,'') AS 'waar',
                coalesce(echelon.Street,'') + '|' + coalesce(echelon.zipcode,'') + '|' + 
                    coalesce(echelon.City,'') + '|' + coalesce(echelon.RedCrossEntityName,'') AS 'waar_E'
            FROM RVW_vwAdresboekVrijwilligers av
            LEFT JOIN City c ON av.CityID = c.CityID
            LEFT JOIN AliasPerson ap ON av.PersonID = ap.PersonID
            LEFT JOIN Alias a1 ON ap.AliasID = a1.AliasID
            LEFT JOIN FunctionPerson fp ON av.PersonID = fp.PersonID
            LEFT JOIN 
                (
                    SELECT RedCrossEntity.RedCrossEntityID, RedCrossEntity.RedCrossEntityName, RedCrossEntity.street, City.zipcode, City.city
                    FROM RedCrossEntity
                    LEFT JOIN City ON RedCrossEntity.CityID = City.CityID
                ) as echelon ON echelon.RedCrossEntityID = fp.RedCrossEntityID

            LEFT JOIN [Function] f ON f.FunctionID = fp.FunctionID
            LEFT JOIN AliasFunction af ON af.FunctionID = f.FunctionID
            LEFT JOIN Alias a2 ON a2.AliasID = af.AliasID
            LEFT JOIN FunctionRaad fr ON fr.FunctionID = f.FunctionID
            LEFT JOIN Raad r ON r.RaadID = fr.RaadID
            LEFT JOIN RedCrossInstitution rci ON rci.RedCrossInstitutionID = fp.RedCrossInstitutionID
            INNER Join FunctionResponsibility FRes on FRes.functionid = f.functionid
            WHERE FRes.ResponsibilityTypeId = 4
------------------------- END -----------------------
            ) data      
        WHERE (wie LIKE '%jos%' OR waar LIKE '+++++'  )
        ORDER BY [type]

答案 1 :(得分:1)

问题在于您正在进行通配符搜索,查找包含在您正在搜索的字段内的任何位置的特定字符串。如果这是性能关键,并且无法使您的搜索更具体,请考虑使用全文搜索:

  

LIKE与全文搜索的比较

     

与全文搜索相比,LIKE Transact-SQL谓词仅适用于字符模式。此外,您不能使用LIKE谓词来查询格式化的二进制数据。此外,针对大量非结构化文本数据的LIKE查询比针对相同数据的等效全文查询慢得多。对数百万行文本数据的LIKE查询可能需要几分钟才能返回;而对于相同的数据,全文查询只需几秒或更短时间,具体取决于返回的行数。

请注意,全文搜索是SQL Server的一个独立组件,它自行安装和管理,因此如果该开销值得获得可能的性能提升,则必须自行评估。有关详细信息,请参阅Full-Text Search (SQL Server)

答案 2 :(得分:0)

在查询中使用wie运算符时,SQL Server很难在waarLIKE列上使用索引。

此处提供更多信息:http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108354.aspx

编辑:如果您尝试实施搜索功能,那么您可以查看Full Text Search

答案 3 :(得分:0)

来自MSDN的这个article讨论了当LIKE子句的WHERE谓词以通配符%开头时的性能。