具有“HAVING Count(BookedForUserID)= 1”的SQL查询优化

时间:2017-09-25 13:57:21

标签: sql sql-server

任何人都可以为我优化查询3。目前,获取6345条记录需要9秒钟。

查询1:

INSERT INTO @AllTraveler
(T.[ID], [Gender], [AirPassengerTypeID], [GivenName], [MiddleName], [SurName], [BirthDate], [NationalityCountryID], [PassportNumber], [PassportExpiryDate],
[PassportIssuedInCountryID], [TitleID], [UserID])
SELECT T.[ID], [Gender], AT.[AirPassengerTypeID], [GivenName], [MiddleName], [SurName], [BirthDate], [NationalityCountryID], [PassportNumber], [PassportExpiryDate],
    [PassportIssuedInCountryID], [TitleID], [BF].Email
FROM Traveler T
    INNER JOIN BFILE BF WITH(READPAST) ON T.BookingFIleID = BF.ID
    LEFT OUTER JOIN ATraveler AT WITH(READPAST) ON AT.TravelerID = T.ID
    LEFT OUTER JOIN HTraveler HT WITH(READPAST) ON HT.TravelerID = T.ID
    LEFT OUTER JOIN STraveler ST WITH(READPAST) ON ST.TravelerID = T.ID 
WHERE
    BF.BookingFileStatusID >= 16 AND [AirPassengerTypeID] IS NOT NULL
    AND[Gender] IS NOT NULL AND[TitleID] IS NOT NULL
GROUP BY T.[ID], BF.ID, T.[Gender], AT.[AirPassengerTypeID], [GivenName], [MiddleName], [SurName], [BirthDate], [NationalityCountryID], [PassportNumber], [PassportExpiryDate],
    [PassportIssuedInCountryID], [TitleID], [BF].Email, T.BookingFIleID,  BF.BookingFileStatusID
ORDER BY
    BF.ID DESC, T.[ID]DESC

查询2:

INSERT INTO @User(ID, BookedForUserID)
SELECT ROW_NUMBER() OVER(ORDER BY Email) as 'ID', Email
FROM BookingFile WITH(READPAST)
WHERE BookingFileStatusID >= 16 
GROUP BY Email

查询3:

INSERT INTO @TempNameAll ([GivenName], [SurName], [Email])
SELECT GivenName, SurName, US.BookedForUserID, 
FROM @AllTraveler AS AT INNER JOIN @User AS US ON AT.UserID = US.BookedForUserID
GROUP BY GivenName,SurName, US.BookedForUserID
HAVING Count(BookedForUserID) = 1

1 个答案:

答案 0 :(得分:2)

对我来说明显的问题是使用表变量。我看到的指南是,如果你有超过100行,将数据粘贴在临时表中。

以下引用自https://docs.microsoft.com/en-us/sql/t-sql/data-types/table-transact-sql

  

表变量没有分布统计信息,它们不会触发重新编译。因此,在许多情况下,优化器将在假设表变量没有行的情况下构建查询计划。因此,如果您期望有更多行(大于100),则应谨慎使用表变量。在这种情况下,临时表可能是更好的解决方案。