如何使用MIN MAX函数优化SQL查询

时间:2017-09-19 13:33:51

标签: sql sql-server performance database-performance

这是我的查询

SELECT
    [Car].CarId AS Id,
    CAST(MIN(ISNULL([Dates].StartDate, [Reco].InsStartDate)) AS date) AS StartDate,
    CAST(MAX(ISNULL([Dates].EndDate, [Reco].InsEndDate)) AS date) AS EndDate
FROM
    dbo.TabReco [Reco]
    INNER JOIN dbo.Insurance [INS] ON [INS].InsId = [Reco].InsId
    INNER JOIN dbo.InsuranceCar [Details] ON [Details].INSCarId = [INS].INSCarId
    INNER JOIN dbo.CarHistory [Car] ON [Car].CarHistId = [Details].CarHistId
    INNER JOIN dbo.InsuranceRiskDates [Dates] ON [Dates].INSId = [INS].INSId
GROUP BY
    [Reco].Number,
    [Car].CarId

当我运行此查询时,需要花费很多时间。问题在于日期的MIN / MAX部分。

CAST(MIN(ISNULL([Dates].StartDate, [Reco].InsStartDate)) AS date) AS StartDate,
CAST(MAX(ISNULL([Dates].EndDate, [Reco].InsEndDate)) AS date) AS EndDate

如果我删除该部分,则查询工作更快。有没有办法优化这样的查询?或者它是不可能的。

1 个答案:

答案 0 :(得分:0)

当您使用INNER JOIN时,看起来您不需要ISNULL。

不要为此烦恼,只需删除那部分。

除非你在[日期] .StartDate和[Dates] .EndDate上允许null 或者如果你使用LEFT JOIN:

SELECT
    [Car].CarId AS Id,
    CAST(MIN(ISNULL([Dates].StartDate, [Reco].InsStartDate)) AS date) AS StartDate,
    CAST(MAX(ISNULL([Dates].EndDate, [Reco].InsEndDate)) AS date) AS EndDate
FROM
    dbo.TabReco [Reco]
    INNER JOIN dbo.Insurance [INS] ON [INS].InsId = [Reco].InsId
    INNER JOIN dbo.InsuranceCar [Details] ON [Details].INSCarId = [INS].INSCarId
    INNER JOIN dbo.CarHistory [Car] ON [Car].CarHistId = [Details].CarHistId
    LEFT JOIN dbo.InsuranceRiskDates [Dates] ON [Dates].INSId = [INS].INSId
GROUP BY
    [Reco].Number,
    [Car].CarId

您可能需要索引连接区域中不是主键的每列。

编辑:我有一个想法,除了索引,试试这个:

SELECT Id,
CAST(MIN(StartDate) AS date) AS StartDate,
CAST(MIN(EndDate) AS date) AS EndDate
FROM
( 
    SELECT [Reco].Number,
    [Car].CarId AS Id,
    [Dates].StartDate, [Dates].EndDate
    FROM
    dbo.TabReco [Reco]
    INNER JOIN dbo.Insurance [INS] ON [INS].InsId = [Reco].InsId
    INNER JOIN dbo.InsuranceCar [Details] ON [Details].INSCarId = [INS].INSCarId
    INNER JOIN dbo.CarHistory [Car] ON [Car].CarHistId = [Details].CarHistId
    INNER JOIN dbo.InsuranceRiskDates [Dates] ON [Dates].INSId = [INS].INSId
    WHERE [Dates].StartDate IS NOT NULL

    UNION ALL

    SELECT [Reco].Number,
    [Car].CarId AS Id,
    [Reco].InsStartDate AS StartDate, 
    [Reco].InsEndDate AS EndDate
    FROM
    dbo.TabReco [Reco]
    INNER JOIN dbo.Insurance [INS] ON [INS].InsId = [Reco].InsId
    INNER JOIN dbo.InsuranceCar [Details] ON [Details].INSCarId = [INS].INSCarId
    INNER JOIN dbo.CarHistory [Car] ON [Car].CarHistId = [Details].CarHistId
    LEFT JOIN dbo.InsuranceRiskDates [Dates] ON [Dates].INSId = [INS].INSId
    WHERE [Dates].StartDate IS NULL
) x
GROUP BY Number, Id