与SQL Server 2005相比,SQL Server 2012中的查询速度要慢得多

时间:2014-05-16 13:31:35

标签: sql sql-server performance sql-server-2012

最近我们将数据库从SQL Server 2005迁移到SQL Server 2012.从那时起,当我们使用以下查询时遇到性能问题:

SELECT     
    dbo.Candidates.CandidateID AS Candidates_CandidateID, 
    dbo.Candidates.DateCreated AS Candidates_DateCreated, 
    dbo.Candidates.Gender AS Candidates_Gender, 
    dbo.Titles.TitleName AS Titles_TitleName, 
    dbo.Addresses.CityName AS Addresses_CityName, 
    dbo.Countries.CountryName AS Candidates_CountryName, 
    dbo.Candidates.PhoneNumber AS Candidates_PhoneNumber, 
    dbo.Candidates.MobilePhoneNumber AS Candidates_MobilePhoneNumber, 
    dbo.Candidates.BirthDate AS Candidates_BirthDate, 
    dbo.vwConcatenatedBranchesPerCandidate.Branches_BrancheName, 
    dbo.States.StateName AS States_StateName, 
    dbo.SubStates.SubStateName AS SubStates_SubStateName, 
    dbo.Candidates.StateDate AS Candidates_StateDate, 
    dbo.Candidates.Nationality AS Candidates_Nationality, 
    dbo.Candidates.AvailableFromDate AS Candidates_AvailableFromDate, 
    dbo.Candidates.AvailableUntilDate AS Candidates_AvailableUntilDate, 
    dbo.Availabilities.AvailabilityName AS Availabilities_AvailabilityName, 
    dbo.AvailableDurations.AvailableDurationName AS AvailableDurations_AvailableDurationName, 
    dbo.Candidates.HoursPerWeekMin AS Candidates_HoursPerWeekMin, 
    dbo.Candidates.HoursPerWeekMax AS Candidates_HoursPerWeekMax, 
    dbo.vwCandidatesLastLetter.Candidates_DateLastLetter, 
    dbo.vwCandidatesLastEmail.Candidates_DateLastEmail, 
    dbo.Candidates.FirstName AS Candidates_FirstName, 
    dbo.Candidates.Initials AS Candidates_Initials, 
    dbo.Candidates.Infix AS Candidates_Infix, 
    dbo.Candidates.Surname AS Candidates_Surname, 
    dbo.vwConcatenatedEmailAddressesPerCandidate.Email AS EmailAddresses_EmailAddress, 
    dbo.vwConcatenatedCurrentFunctionNamesPerCandidate.Candidates_CurrentFunctionNames, 
    dbo.CandidateSources.SourceName AS CandidateSources_SourceName,
    dbo.Candidates.CandidateSourceText AS Candidates_CandidateSourceText, CandidateIsActiveInAMatch.Candidates_ActiveInOtherMatch, 
    dbo.vwCandidatesUsersFullName.Candidates_FullUserName, 
    dbo.Candidates.Remark AS Candidates_Remark, 
    dbo.Candidates.HasWorkedForUs AS Candidates_HasWorkedForUs, 
    dbo.GenerateFullName(dbo.Candidates.Surname, dbo.Candidates.FirstName, dbo.Candidates.Initials, dbo.Candidates.Infix) AS Candidates_FullName, 
    dbo.vwCandidatesLastMarketingMail.Candidates_DateMarketingMail, 
    dbo.Addresses.StreetName AS Addresses_StreetName, 
    dbo.Addresses.PostalCode AS Addresses_PostalCode, 
    dbo.Candidates.AvailabilityNote, 
    dbo.Candidates.Greeting, 
    dbo.Candidates.StartDate AS Candidates_StartDate, 
    dbo.Candidates.EndDate AS Candidates_EndDate
FROM         
    dbo.vwCandidatesLastEmail RIGHT OUTER JOIN
    dbo.CandidateSources RIGHT OUTER JOIN
    dbo.Candidates LEFT OUTER JOIN
    dbo.vwCandidatesLastMarketingMail ON dbo.Candidates.CandidateID = dbo.vwCandidatesLastMarketingMail.Candidates_CandidateID LEFT OUTER JOIN
    dbo.Titles ON dbo.Candidates.TitleID = dbo.Titles.TitleID LEFT OUTER JOIN
    dbo.vwCandidatesUsersFullName ON dbo.Candidates.CandidateID = dbo.vwCandidatesUsersFullName.Candidates_CandidateID LEFT OUTER JOIN
    dbo.CandidateIsActiveInAMatch() AS CandidateIsActiveInAMatch ON dbo.Candidates.CandidateID = CandidateIsActiveInAMatch.CandidateID ON 
    dbo.CandidateSources.CandidatesSourceID = dbo.Candidates.CandidateSourceID LEFT OUTER JOIN
    dbo.vwConcatenatedCurrentFunctionNamesPerCandidate ON 
    dbo.Candidates.CandidateID = dbo.vwConcatenatedCurrentFunctionNamesPerCandidate.CandidateID LEFT OUTER JOIN
    dbo.vwConcatenatedEmailAddressesPerCandidate ON dbo.Candidates.CandidateID = dbo.vwConcatenatedEmailAddressesPerCandidate.CandidateID LEFT OUTER JOIN
    dbo.AvailableDurations ON dbo.Candidates.AvailableDurationID = dbo.AvailableDurations.AvailableDurationID LEFT OUTER JOIN
    dbo.Availabilities ON dbo.Candidates.AvailabilityID = dbo.Availabilities.AvailabilityID LEFT OUTER JOIN
    dbo.vwConcatenatedBranchesPerCandidate ON dbo.Candidates.CandidateID = dbo.vwConcatenatedBranchesPerCandidate.CandidateID LEFT OUTER JOIN
    dbo.States ON dbo.Candidates.StateID = dbo.States.StateID LEFT OUTER JOIN
    dbo.SubStates ON dbo.Candidates.SubStateID = dbo.SubStates.SubStateID AND dbo.States.StateID = dbo.SubStates.StateID ON 
    dbo.vwCandidatesLastEmail.Candidates_CandidateID = dbo.Candidates.CandidateID LEFT OUTER JOIN
    dbo.vwCandidatesLastLetter ON dbo.Candidates.CandidateID = dbo.vwCandidatesLastLetter.Candidates_CandidateID LEFT OUTER JOIN
    dbo.Countries INNER JOIN
    dbo.Addresses ON dbo.Countries.CountryID = dbo.Addresses.CountryID ON dbo.Candidates.AddressID = dbo.Addresses.AddressID

查询使用一些使用自定义用户定义的聚合连接函数的子视图(视图以vwConcatenated开头...),一些子视图使用以下查询(它们都以LastEmail,LastLetter等结尾...):

SELECT        
    dbo.Candidates.CandidateID AS Candidates_CandidateID, 
    MAX(dbo.Actions.DateCreated) AS Candidates_DateLastEmail
FROM
    dbo.Candidates 
INNER JOIN
    dbo.Actions_Candidates 
ON 
    dbo.Candidates.CandidateID = dbo.Actions_Candidates.CandidateID 
INNER JOIN
    dbo.Actions 
ON 
    dbo.Actions_Candidates.ActionID = dbo.Actions.ActionID 
INNER JOIN
    dbo.ActionTypes 
ON 
    dbo.Actions.ActionTypeID = dbo.ActionTypes.ActionTypeID
WHERE
    (dbo.ActionTypes.ActionTypeCodeInternal = N'CANDIDATE_EMAIL') OR
    (dbo.ActionTypes.ActionTypeCodeInternal = N'SENT_EMAIL')
GROUP BY dbo.Candidates.CandidateID

在SQL Server 2012中,此查询会抛出一条警告,其中包含以下消息:操作员使用tempdb在溢出级别为1的执行期间溢出数据。

它看起来似乎没有缓存查询,因为当我第二次运行相同的查询时,它只需要上一次尝试。当我在SQL 2005中运行相同的查询两次,然后第二次在秒内返回。

为什么SQL Server 2012和2005处理查询的方式如此不同?为什么SQL 2012中的查询速度要慢得多?

执行计划的链接

0 个答案:

没有答案