2016-04-04 5 views
0

Diese Abfrage funktioniert bereits, aber ich bekomme Berichte von "Resource Limit Exceeded", die mir Angst machen.effizientere Abfrage für das Ausreißen des Verlaufs

Ich habe drei Tabellen: mainTable, sideTable und leftJoin.

mainTable ist zwei Mitarbeiternummern zugeordnet, da sie alleine oder zu zweit arbeiten können.

sideTable hat den Namen des Mitarbeiters.

LeftJoin hat die Mitarbeiteraktivität, die eine große Tabelle von Aktivitäten ist, wo ich den neuesten Status bekommen muss.

Ich weiß nicht, ob das eine gute Abfrage ist oder nicht, aber es ruft zweimal die sideTable auf und ruft das LeftJoin zweimal auf.

Diese Abfrage ist 12 Sekunden.

WITH cteTbl AS (
    SELECT 
     EmployeeID 
     ,MAX(TIMESTAMP(StampDate, StampTime)) AS cteMaxTime 
    FROM 
     /**/ getMaxDateTime 
    GROUP BY EmployeeID 
) 
SELECT 
    /* stuff */ 
    ,sideTable1.EmployeeName1 
    ,sideTable2.EmployeeName2 
    ,leftJoinA.EmployeeStatus 
    ,leftJoinB.EmployeeStatus 


FROM 
    /**/ mainTable 

LEFT JOIN /**/ sideTable1 
    ON mainTable.employeeNumber = sideTable1.employeeNumber 

LEFT JOIN /**/ sideTable2 
    ON mainTable.employeeNumber = sideTable2.employeeNumber 

    /*tons of left joins*/ 


LEFT JOIN 
(
    SELECT  leftJoinA.EmployeeNumber, leftJoinA.EmployeeStatus 
    FROM  /**/ leftJoinA 
    INNER JOIN cteTbl 
     ON leftjoinA.EmployeeNumber = cteTbl.EmployeeNumber 
      AND TIMESTAMP(leftjoinA.StampDate,leftjoinA.StampTime) = cteTbl.cteMaxTime 
) innerStampData1 
    ON sideTable1.EmployeeNumber1 = innerStampData1.EmployeeNumber 


LEFT JOIN 
(
    SELECT  leftJoinB.EmployeeNumber, leftJoinB.EmployeeStatus 
    FROM  /**/ leftJoinB 
    INNER JOIN cteTbl 
     ON leftjoinB.EmployeeNumber = cteTbl.EmployeeNumber 
      AND TIMESTAMP(leftjoinB.StampDate,leftjoinB.StampTime) = cteTbl.cteMaxTime 
) innerStampData2 
    ON sideTable2.EmployeeNumber2 = innerStampData2.EmployeeNumber 

WHERE 
    /**/ 

GROUP BY 
    /**/ 

ORDER BY 
    /**/ 

Wenn ich dies tun, wird die Abfrage sieben Sekunden, aber die Ergebnisse sind für jedes Team dupliziert.

LEFT JOIN 
(
    SELECT  leftJoinA.EmployeeNumber, leftJoinA.EmployeeStatus 
    FROM  /**/ leftJoinA 
    INNER JOIN cteTbl 
     ON leftjoinA.EmployeeNumber = cteTbl.EmployeeNumber 
      AND TIMESTAMP(leftjoinA.StampDate,leftjoinA.StampTime) = cteTbl.cteMaxTime 
) innerStampData1 
    ON sideTable.EmployeeNumber1 = innerStampData1.EmployeeNumber OR sideTable2.EmployeeNumber = innerStampData2.EmployeeNumber 
+0

welche Indizes Sie auf dieser Tabellen haben? –

+0

es ist schwierig, eine bessere Abfrage zu finden, wenn Sie nur einen Teil von sql schreiben, keine Definitionen von Tabellen schreiben und keine Beispieldaten schreiben ... –

Antwort

0

versuchen, diese Abfrage:

WITH 
    cteTbl AS (
    SELECT EmployeeID 
    , MAX(TIMESTAMP(StampDate, StampTime)) AS cteMaxTime 
    FROM /**/ getMaxDateTime 
    GROUP BY EmployeeID) 
SELECT 
/* stuff */ 
    sideTable1.EmployeeName1 
, sideTable2.EmployeeName2 
, innerStampData1.EmployeeStatus 
, innerStampData2.EmployeeStatus 
FROM /**/ mainTable 
LEFT JOIN /**/ sideTable1 
    ON mainTable.employeeNumber = sideTable1.employeeNumber 
LEFT JOIN /**/ sideTable2 
    ON mainTable.employeeNumber = sideTable2.employeeNumber 
    /*tons of left joins*/ 
LEFT JOIN ( 
    SELECT EmployeeNumber 
    , EmployeeStatus 
    FROM /**/ leftJoinA 
    WHERE EXISTS(SELECT 1 FROM cteTbl 
    WHERE leftjoinA.EmployeeNumber = cteTbl.EmployeeNumber 
    AND TIMESTAMP(leftjoinA.StampDate,leftjoinA.StampTime) = cteTbl.cteMaxTime) 
) innerStampData1 
    ON (sideTable1.EmployeeNumber1 = innerStampData1.EmployeeNumber 
    OR sideTable2.EmployeeNumber2 = innerStampData2.EmployeeNumber) 

WHERE 
    /**/ 
GROUP BY 
    /**/ 
ORDER BY 
    /**/ 
Verwandte Themen