2017-09-19 2 views
0

Dies ist meine AbfrageWie SQL-Abfrage mit MIN MAX-Funktion

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 

Wenn ich diese Abfrage ausführen es braucht viel Zeit zu optimieren. Das Problem ist mit Teil MIN/MAX für Daten.

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

Wenn ich diesen Teil entfernen, funktioniert die Abfrage schneller. Gibt es eine Möglichkeit, eine solche Abfrage zu optimieren? Oder es ist unmöglich.

+2

Können Sie den Ausführungsplan erstellen? Ohne irgendeine Art von Details erraten wir nur. –

+0

Wenn Sie Indizes für die Schlüssel haben, die für den 'Join' verwendet werden, können Sie wenig tun. –

+0

Wenn Ihre Daten * als DATUM * gespeichert wurden, können Sie möglicherweise einige clevere Indizes hinzufügen, um dies zu beheben. Da sie es nicht sind, ist das beste, was Sie tun können, ein Deckungsindex, der helfen kann oder auch nicht. In jedem Fall müssen wir noch einen Abfrageplan sehen. – RBarryYoung

Antwort

0

Es sieht so aus, als ob Sie ISNULL nicht benötigen, wenn Sie INNER JOIN verwenden.

Nicht stören, nur diesen Teil entfernen.

außer wenn Sie erlauben null auf [Daten] .StartDate und [Termine] .EndDate oder wenn Sie 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 

Sie Index im Bereich beitreten für jede Spalte benötigen, die nicht ist Primärschlüssel.

Editiert: Ich habe eine Idee neben Indizierung haben, versuchen Sie dies:

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 
+0

ISNULL ist kein Problem, das Problem ist mit MIN MAX, weil es Tausende Datensätze gibt – DiPix