簡體   English   中英

SQL 服務器查詢的性能問題

[英]Performance issue with SQL Server 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 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)

但這甚至更慢。

有沒有人看到加快速度的方法?

請刪除IN並將其替換為 join ,如下所述。 通過這種方式,我們可以避免由於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]

問題是您正在執行通配符搜索,尋找包含在您正在搜索的字段內任何位置的特定字符串。 如果這對性能至關重要並且無法使您的搜索更加具體,請考慮使用全文搜索:

LIKE 與全文搜索的比較

與全文搜索相比,LIKE Transact-SQL 謂詞僅適用於字符模式。 此外,您不能使用 LIKE 謂詞來查詢格式化的二進制數據。 此外,針對大量非結構化文本數據的 LIKE 查詢比針對相同數據的等效全文查詢要慢得多。 對數百萬行文本數據的 LIKE 查詢可能需要幾分鍾才能返回; 而對於相同的數據,全文查詢可能只需要幾秒鍾或更短的時間,具體取決於返回的行數。

請注意,全文搜索是 SQL 服務器的一個單獨組件,它自行安裝和管理,因此您必須自己評估這種開銷是否值得可能的性能提升。 有關詳細信息,請參閱全文搜索 (SQL Server)

當您在查詢中使用LIKE運算符時,SQL 服務器將難以在wiewaar列上使用索引。

更多信息在這里: http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108354.aspx

編輯:如果您正在嘗試實現搜索功能,那么您可以查看全文搜索

MSDN 的這篇文章討論了WHERE子句的LIKE謂詞以通配符%開頭時的性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM