【问题标题】:SQL Server : Issue in exists query replace with joinsSQL Server:存在查询替换为联接中的问题
【发布时间】:2017-08-21 04:12:12
【问题描述】:

我正在使用以下代码来获取报告。

DECLARE @CountryID smallint = 100
DECLARE @UTCTDIM smallint = 330
DECLARE @MarketProfileID smallint = 2
DECLARE @StartDate datetime = '2017-01-01'
DECLARE @EndDate datetime = '2017-01-03'
DECLARE @CustomerTypeID smallint = 1

SET NOCOUNT ON
DECLARE @AirportList TABLE (ID bigint)
INSERT INTO @AirportList (ID)
SELECT
    DISTINCT Airport.ID
FROM
    Airport
    INNER JOIN CityList ON Airport.CityID = CityList.ID
    INNER JOIN CountryList ON CityList.CountryID = CountryList.ID
where
    CountryList.NameEN in ('San Marino','Serbia','Slovakia','Slovenia','Spain','Sweden','Switzerland','Turkey','Ukraine','United Kingdom','Vatican CityList')

DECLARE @TempSales TABLE
(   
    [Type] varchar(50),
    [From] char(3),
    [To] char(3),
    [Tickets] bigint,
    [Average fare] decimal(18,3),
    [Net sale] decimal(18,3)
)

INSERT INTO @TempSales
SELECT 
    [AirTrips].[NameEN] AS [Type],
    [Airport1].[IATACode] AS [From],
    [Airport2].[IATACode] AS [To],
    NULL,
    AVG(ISNULL([AirTraveler].[FareBaseAmount], 0)) + AVG(ISNULL([AirTraveler].[Taxes], 0)) AS [Average fare],
    SUM(ISNULL([AirTraveler].[AmountNetRemit], 0)) AS [Net sale]
FROM
    [BookingDetails] WITH (READPAST)
    INNER JOIN [Bookings] WITH (READPAST) ON Booking.BookingFileID = BookingFile.ID
    INNER JOIN [AirTrips] WITH (READPAST) ON Booking.AirTripTypeID = AirTrips.ID
    INNER JOIN [AirTraveler] WITH (READPAST) ON AirTraveler.BookingID = Booking.ID
    INNER JOIN [AirOrigin] WITH (READPAST) ON AirOrigin.BookingID = Booking.ID
    INNER JOIN [Airport] AS [Airport1] WITH (READPAST) ON [Airport1].[ID] = [AirOrigin].[DepartureAirportID] 
    INNER JOIN [Airport] AS [Airport2] WITH (READPAST) ON [Airport2].[ID] = [AirOrigin].[ArrivalAirportID]
WHERE
    [Bookings].[BookingStatusID] IN (16, 20, 22, 23) 
    AND [Bookings].[IsActive] = 1 
    AND [AirOrigin].[AirTripDirectionTypeID] = 1 
    AND (ISNULL([AirTraveler].[BaseAmountNetRemit], 0) + ISNULL([AirTraveler].[TaxesNetRemit], 0)) <> 0 
    AND [Bookings].[RemitDate] BETWEEN @StartDate AND @EndDate
    AND [BookingDetails].[MarketProfileID] = @MarketProfileID 
    AND [BookingDetails].[BookedForOrganizationID] IS NULL
    AND (
        EXISTS (SELECT A.ID FROM @AirportList A WHERE A.ID = [Airport1].ID)
        OR
        EXISTS (SELECT A.ID FROM @AirportList A WHERE A.ID = [Airport2].ID)
    )
GROUP BY
    [AirTrips].[NameEN],
    [Airport1].[IATACode],
    [Airport2].[IATACode]

INSERT INTO @TempSales
SELECT
    [AirTrips].[NameEN] AS [Type],
    [Airport1].[IATACode] AS [From],
    [Airport2].[IATACode] AS [To],
    COUNT(*) [Tickets],
    NULL,
    NULL
FROM
    [BookingDetails] WITH (READPAST)
    INNER JOIN [Bookings] WITH (READPAST) ON Booking.BookingFileID = BookingFile.ID
    INNER JOIN [AirTrips] WITH (READPAST) ON Booking.AirTripTypeID = AirTrips.ID
    INNER JOIN [AirTraveler] WITH (READPAST) ON AirTraveler.BookingID = Booking.ID
    INNER JOIN [AirOrigin] WITH (READPAST) ON AirOrigin.BookingID = Booking.ID
    INNER JOIN [Airport] AS [Airport1] WITH (READPAST) ON [Airport1].[ID] = [AirOrigin].[DepartureAirportID] 
    INNER JOIN [Airport] AS [Airport2] WITH (READPAST) ON [Airport2].[ID] = [AirOrigin].[ArrivalAirportID] 
WHERE
    [Bookings].[BookingStatusID] IN (16, 22, 23)
    AND [Bookings].[IsActive] = 1
    AND [AirOrigin].[AirTripDirectionTypeID] = 1
    AND (ISNULL([AirTraveler].[BaseAmountNetRemit], 0) + ISNULL([AirTraveler].[TaxesNetRemit], 0)) <> 0
    AND [Bookings].[RemitDate] BETWEEN @StartDate AND @EndDate
    AND [BookingDetails].[MarketProfileID] = @MarketProfileID 
    AND [BookingDetails].[BookedForOrganizationID] IS NULL
    AND (
        EXISTS (SELECT A.ID FROM @AirportList A WHERE A.ID = [Airport1].ID)
        OR
        EXISTS (SELECT A.ID FROM @AirportList A WHERE A.ID = [Airport2].ID)
    )
GROUP BY
    [AirTrips].[NameEN],
    [Airport1].[IATACode],
    [Airport2].[IATACode]

SELECT  
    [Type],
    [From],
    [To],
    COALESCE( SUM([Tickets]), 0) AS [Tickets],
    COALESCE( SUM([Average fare]), 0) AS [Average fare],
    COALESCE( SUM([Net sale]), 0) AS [Net sale]
FROM 
    @TempSales
GROUP BY
    [Type],
    [From],
    [To]
ORDER BY 
    [Tickets] DESC,
    [Type] ASC,
    [From] ASC,
    [To] ASC

我在数据库中有数百万条记录。 对于小记录 (2,3) 天,它工作正常。 但是对于大型记录(10 天),我遇到了资源锁定/超时错误。

我发现以下代码存在一个问题:

AND (
        EXISTS (SELECT A.ID FROM @AirportList A WHERE A.ID = [Airport1].ID)
        OR
        EXISTS (SELECT A.ID FROM @AirportList A WHERE A.ID = [Airport2].ID)
    )

如果我删除此代码。我不会遇到太多问题。 请帮我找到另一种方法来编写此代码或优化它

【问题讨论】:

  • 我认为它不能解决您的问题,但我认为您可以将您的条件重写为EXISTS ( SELECT A.ID FROM @AirportList A WHERE A.ID IN (Airport1.ID, Airport2.ID) ) 并重试。你能发布解释计划吗?
  • 您是否尝试过对 @AirportList 表进行 INNER JOIN,其中 A.ID 将等于 [Airport1].ID 或 [Airport2].ID ??
  • @etsa : 没有任何区别
  • @ Abdullah Dibas : 你能帮帮我吗

标签: sql sql-server join exists sql-optimization


【解决方案1】:

试试这个:

 DECLARE @CountryID smallint = 100
    DECLARE @UTCTDIM smallint = 330
    DECLARE @MarketProfileID smallint = 2
    DECLARE @StartDate datetime = '2017-01-01'
    DECLARE @EndDate datetime = '2017-01-03'
    DECLARE @CustomerTypeID smallint = 1

    SET NOCOUNT ON
    DECLARE @AirportList TABLE (ID bigint)
    INSERT INTO @AirportList (ID)
    SELECT
       DISTINCT Airport.ID
    FROM
      Airport
    INNER JOIN CityList ON Airport.CityID = CityList.ID
    INNER JOIN CountryList ON CityList.CountryID = CountryList.ID
    where
       CountryList.NameEN in ('San   Marino','Serbia','Slovakia','Slovenia','Spain','Sweden','Switzerland','Turkey','Ukraine','United Kingdom','Vatican CityList')

DECLARE @TempSales TABLE
(   
    [Type] varchar(50),
    [From] char(3),
    [To] char(3),
    [Tickets] bigint,
    [Average fare] decimal(18,3),
    [Net sale] decimal(18,3)
)

INSERT INTO @TempSales
SELECT 
    [AirTrips].[NameEN] AS [Type],
    [Airport1].[IATACode] AS [From],
    [Airport2].[IATACode] AS [To],
    NULL,
    AVG(ISNULL([AirTraveler].[FareBaseAmount], 0)) + AVG(ISNULL([AirTraveler].[Taxes], 0)) AS [Average fare],
    SUM(ISNULL([AirTraveler].[AmountNetRemit], 0)) AS [Net sale]
FROM
    [BookingDetails] WITH (READPAST)
    INNER JOIN [Bookings] WITH (READPAST) ON Booking.BookingFileID = BookingFile.ID
    INNER JOIN [AirTrips] WITH (READPAST) ON Booking.AirTripTypeID = AirTrips.ID
    INNER JOIN [AirTraveler] WITH (READPAST) ON AirTraveler.BookingID = Booking.ID
    INNER JOIN [AirOrigin] WITH (READPAST) ON AirOrigin.BookingID = Booking.ID
    INNER JOIN [Airport] AS [Airport1] WITH (READPAST) ON [Airport1].[ID] = [AirOrigin].[DepartureAirportID] 
    INNER JOIN [Airport] AS [Airport2] WITH (READPAST) ON [Airport2].[ID] = [AirOrigin].[ArrivalAirportID]
    INNER JOIN @AirportList AS A ON  A.ID = [AirOrigin].[DepartureAirportID] OR A.ID = [AirOrigin].[ArrivalAirportID] 
WHERE
    [Bookings].[BookingStatusID] IN (16, 20, 22, 23) 
    AND [Bookings].[IsActive] = 1 
    AND [AirOrigin].[AirTripDirectionTypeID] = 1 
    AND (ISNULL([AirTraveler].[BaseAmountNetRemit], 0) + ISNULL([AirTraveler].[TaxesNetRemit], 0)) <> 0 
    AND [Bookings].[RemitDate] BETWEEN @StartDate AND @EndDate
    AND [BookingDetails].[MarketProfileID] = @MarketProfileID 
    AND [BookingDetails].[BookedForOrganizationID] IS NULL
GROUP BY
    [AirTrips].[NameEN],
    [Airport1].[IATACode],
    [Airport2].[IATACode]

INSERT INTO @TempSales
SELECT
    [AirTrips].[NameEN] AS [Type],
    [Airport1].[IATACode] AS [From],
    [Airport2].[IATACode] AS [To],
    COUNT(*) [Tickets],
    NULL,
    NULL
FROM
    [BookingDetails] WITH (READPAST)
    INNER JOIN [Bookings] WITH (READPAST) ON Booking.BookingFileID = BookingFile.ID
    INNER JOIN [AirTrips] WITH (READPAST) ON Booking.AirTripTypeID = AirTrips.ID
    INNER JOIN [AirTraveler] WITH (READPAST) ON AirTraveler.BookingID = Booking.ID
    INNER JOIN [AirOrigin] WITH (READPAST) ON AirOrigin.BookingID = Booking.ID
    INNER JOIN [Airport] AS [Airport1] WITH (READPAST) ON [Airport1].[ID] = [AirOrigin].[DepartureAirportID] 
    INNER JOIN [Airport] AS [Airport2] WITH (READPAST) ON [Airport2].[ID] = [AirOrigin].[ArrivalAirportID] 
    INNER JOIN @AirportList AS A ON  A.ID = [AirOrigin].[DepartureAirportID] OR A.ID = [AirOrigin].[ArrivalAirportID] 
WHERE
    [Bookings].[BookingStatusID] IN (16, 22, 23)
    AND [Bookings].[IsActive] = 1
    AND [AirOrigin].[AirTripDirectionTypeID] = 1
    AND (ISNULL([AirTraveler].[BaseAmountNetRemit], 0) + ISNULL([AirTraveler].[TaxesNetRemit], 0)) <> 0
    AND [Bookings].[RemitDate] BETWEEN @StartDate AND @EndDate
    AND [BookingDetails].[MarketProfileID] = @MarketProfileID 
    AND [BookingDetails].[BookedForOrganizationID] IS NULL
GROUP BY
    [AirTrips].[NameEN],
    [Airport1].[IATACode],
    [Airport2].[IATACode]

SELECT  
    [Type],
    [From],
    [To],
    COALESCE( SUM([Tickets]), 0) AS [Tickets],
    COALESCE( SUM([Average fare]), 0) AS [Average fare],
    COALESCE( SUM([Net sale]), 0) AS [Net sale]
FROM 
    @TempSales
GROUP BY
    [Type],
    [From],
    [To]
ORDER BY 
    [Tickets] DESC,
    [Type] ASC,
    [From] ASC,
    [To] ASC

【讨论】:

  • 进入了无限循环。
【解决方案2】:

向临时表添加主键

DECLARE @AirportList TABLE (ID bigint primary key)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多