我正在尝试解决SQL事件探查器中具有大量读取的过程,但在启用统计信息时则不行。这是一个使用分页的过程,我在第400页看到了大约17k的读取,有趣的部分是有时当我重新编译过程时,数字下降到1000-2000,如截图所示。较低的页面显示1000次读取,随着我向上移动,数字会增加:
在SSMS中使用SET STATISTICS IO ON显示大约1000次读取,即使Profiler说有17k:
这是程序的一部分(#users临时表中有4000条记录):
SELECT [temp].[UserID] ,
[temp].[UserName] ,
[temp].[FirstName] ,
[temp].[LastName] ,
[temp].[CommissionRate] ,
[temp].[PhotoURL] ,
[temp].[UserStatusID] ,
[temp].[UserStatus] ,
[temp].[ReceivesCommission] ,
[temp].[CreatedDateTimeUTC] ,
[temp].[UserTypeID] ,
[temp].[UserType] ,
[temp].[CompanyID] ,
[temp].[CompanyName] ,
[temp].[CompanyLegalName] ,
[temp].[CompanyShortName] ,
[aggregate].[EmailAddress] ,
[aggregate].[TelephoneCount] ,
[aggregate].[Telephone] ,
[aggregate].[EmailAddressCount] ,
[address].[Address1] ,
[address].[Address2] ,
[address].[City] ,
[address].[State] ,
[address].[ZipCode]
FROM ( SELECT [user].[UserID] ,
[user].[UserName] ,
[contact].[FirstName] ,
[contact].[LastName] ,
[user].[CommissionRate] ,
[user].[PhotoURL] ,
[userStatus].[UserStatusID] ,
[userStatus].[UserStatus] ,
[user].[ReceivesCommission] ,
[user].[CreatedDateTimeUTC] ,
[userType].[UserTypeID] ,
[userType].[UserType] ,
[user].[CompanyID] ,
[user].[CompanyName] ,
[user].[CompanyLegalName] ,
[user].[CompanyShortName]
FROM [#users] [user]
INNER JOIN [dbo].[UserStatus] [userStatus] ON [userStatus].[UserStatusID] = [user].[UserStatusID]
INNER JOIN [dbo].[UserType] [userType] ON [user].[UserTypeID] = [userType].[UserTypeID]
INNER JOIN [dbo].[Contact] [contact] ON [contact].[ContactID] = [user].[UserID]
AND [contact].[ContactTypeID] = 3
WHERE ( @UserName IS NULL OR [user].[UserName] LIKE '%' + @UserName + '%' )
AND ( @FirstName IS NULL OR [contact].[FirstName] LIKE '%' + @FirstName + '%' )
AND ( @LastName IS NULL OR [contact].[LastName] LIKE '%' + @LastName + '%' )
AND ( @CompanyID IS NULL OR [user].[CompanyID] = @CompanyID )
AND ( @UserStatusID IS NULL OR [user].[UserStatusID] = @UserStatusID )
ORDER BY [contact].[LastName] ,
[contact].[FirstName] ,
[user].[CompanyName] ,
[user].[UserID] DESC
OFFSET ( @PageNumber - 1 ) * @PageSize ROWS
FETCH NEXT @PageSize ROWS ONLY
) [temp]
CROSS APPLY [dbo].[fnContactDetailAggregateGetByContactID]([temp].[UserID]) [aggregate]
LEFT JOIN [dbo].[ContactAddress] [address] ON [address].[ContactID] = [temp].[UserID]
这是功能:
CREATE FUNCTION [dbo].[fnContactDetailAggregateGetByContactID]
(
@ContactID INT
)
RETURNS @contact TABLE
(
[ContactID] INT PRIMARY KEY NOT NULL ,
[TelephoneCount] INT NULL ,
[Telephone] VARCHAR(255) NULL ,
[EmailAddressCount] INT NULL ,
[EmailAddress] VARCHAR(255) NULL
)
WITH SCHEMABINDING
AS
BEGIN
INSERT @contact
SELECT @ContactID ,
SUM(CASE WHEN [temp].[ContactDetailTypeID] = 1 THEN 1
ELSE 0
END) [TelephoneCount] ,
MAX(CASE WHEN [temp].[ContactDetailTypeID] = 1
THEN [temp].[ContactDetailValue]
END) [Telephone] ,
SUM(CASE WHEN [temp].[ContactDetailTypeID] = 3 THEN 1
ELSE 0
END) [EmailAddressCount] ,
MAX(CASE WHEN [temp].[ContactDetailTypeID] = 3
THEN [temp].[ContactDetailValue]
END) [EmailAddress]
FROM ( SELECT [detail].[ContactID] ,
[label].[ContactDetailTypeID] ,
FIRST_VALUE([detail].[ContactDetailValue]) OVER ( PARTITION BY [label].[ContactDetailTypeID] ORDER BY [detail].[Default] DESC ) [ContactDetailValue]
FROM [dbo].[ContactDetail] [detail]
INNER JOIN [dbo].[ContactDetailLabel] [label] ON [label].[ContactDetailLabelID] = [detail].[ContactDetailLabelID]
WHERE [detail].[ContactID] = @ContactID
) [temp]
RETURN
END
任何想法可能导致这种情况以及如何解决这个问题?
答案 0 :(得分:0)
SELECT
t.*,
ut.[userType],
us.[userStatus],
g.[EmailAddress],
g.[TelephoneCount],
g.[Telephone],
g.[EmailAddressCount],
a.[Address1],
a.[Address2],
a.[City],
a.[State],
a.[ZipCode]
FROM (
SELECT
u.*,
c.[FirstName],
c.[LastName],
u.[CommissionRate],
u.[PhotoURL],
u.[UserStatusID],
u.[ReceivesCommission],
u.[CreatedDateTimeUTC],
u.[UserTypeID],
u.[CompanyID],
u.[CompanyName],
u.[CompanyLegalName],
u.[CompanyShortName]
FROM #users u
JOIN dbo.contact c ON c.[ContactID] = u.[UserID] AND c.[ContactTypeID] = 3
WHERE
(@UserName IS NULL OR u.[UserName] LIKE '%' + @UserName + '%')
AND (@FirstName IS NULL OR c.[FirstName] LIKE '%' + @FirstName + '%')
AND (@LastName IS NULL OR c.[LastName] LIKE '%' + @LastName + '%')
AND (@CompanyID IS NULL OR u.[CompanyID] = @CompanyID)
AND (@UserStatusID IS NULL OR u.[UserStatusID] = @UserStatusID)
ORDER BY
c.[LastName],
c.[FirstName],
u.[CompanyName],
u.[UserID] DESC
OFFSET (@PageNumber - 1) * @PageSize ROWS FETCH NEXT @PageSize ROWS ONLY
) t
JOIN dbo.userStatus us ON us.[UserStatusID] = u.[UserStatusID]
JOIN dbo.userType ut ON u.[UserTypeID] = ut.[UserTypeID]
CROSS APPLY (
SELECT
COUNT(CASE WHEN [temp].[ContactDetailTypeID] = 1 THEN 1 END) AS [TelephoneCount],
MAX(CASE WHEN [temp].[ContactDetailTypeID] = 1 THEN [temp].[ContactDetailValue] END) AS [Telephone],
COUNT(CASE WHEN [temp].[ContactDetailTypeID] = 3 THEN 1 END) AS [EmailAddressCount],
MAX(CASE WHEN [temp].[ContactDetailTypeID] = 3 THEN [temp].[ContactDetailValue] END) AS [EmailAddress]
FROM (
SELECT
[detail].[ContactID],
[label].[ContactDetailTypeID],
FIRST_VALUE([detail].[ContactDetailValue]) OVER (PARTITION BY [label].[ContactDetailTypeID] ORDER BY [detail].[default] DESC) [ContactDetailValue]
FROM [dbo].[ContactDetail] [detail]
JOIN [dbo].[ContactDetailLabel] [label] ON [label].[ContactDetailLabelID] = [detail].[ContactDetailLabelID]
WHERE [detail].[ContactID] = t.[UserID]
) [temp]
) g
LEFT JOIN dbo.ContactAddress a ON a.ContactID = t.UserID
OPTION(RECOMPILE)