开发者

Performance issue with SQL Server query

开发者 https://www.devze.com 2023-03-09 23:14 出处:网络
This is my query: SELECT ID, [type], naam, adresl1, adresl2, tel, fax, email, contactpersoon FROM ------------------------ START --------------------------

This is my query:

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 Responsibility开发者_开发问答TypeId = 4)
------------------------- END -----------------------
 ) data     
WHERE 
     (wie LIKE '%jos%' OR waar LIKE '+++++'  )
ORDER BY 
     [type]

The section between -START- and -END- is working fine and executes in about 3 seconds. But when I add the WHERE (wie LIKE '%jos%' OR waar LIKE '+++++' ) it takes 30 seconds to run.

I have tried this too:

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

But that was even slower.

Does anyone see a way to speed this up?


Please remove the IN and replace it with join as mentioned below. In this way we can avoid the looping which is happening due to 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]


The problem is that you're doing a wildcard search, looking for a specific string contained anywhere inside the field you're searching on. If this is performance-critical and there's no way to make your search more specific, consider using Full-Text Search:

Comparison of LIKE to Full-Text Search

In contrast to full-text search, the LIKE Transact-SQL predicate works on character patterns only. Also, you cannot use the LIKE predicate to query formatted binary data. Furthermore, a LIKE query against a large amount of unstructured text data is much slower than an equivalent full-text query against the same data. A LIKE query against millions of rows of text data can take minutes to return; whereas a full-text query can take only seconds or less against the same data, depending on the number of rows that are returned.

Note that Full-Text Search is a separate component of SQL Server that is installed and administered on its own, so you will have to evaluate for yourself if that overhead is worth the possible performance gain. See Full-Text Search (SQL Server) for more information.


This article from MSDN talks about performance when the LIKE predicate of a WHERE clause starts with the wildcard character, %.


SQL server will struggle to use indexes on the wie and waar columns when you use LIKE operators in your query.

More information here: http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108354.aspx

EDIT: If you are trying to implement a search feature, then you could look into Full Text Search

0

精彩评论

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