2016-04-04 2 views
0

Этот запрос уже работает, но я получаю сообщения о «Ограничении ресурсов превышен», что меня пугает.более эффективный запрос на извлечение истории

У меня есть три таблицы: mainTable, sideTable и leftJoin.

mainTable связан с двумя номерами сотрудников, поскольку они могут работать самостоятельно или в паре из двух.

У стороны есть имя сотрудника.

В LeftJoin есть деятельность сотрудника, которая представляет собой большую таблицу действий, в которой я должен получить последний статус.

Я не знаю, является ли это хорошим запросом или нет, но он дважды вызывает sideTable и дважды вызывает LeftJoin.

Этот запрос составляет 12 секунд.

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 
    /**/ 

Если я делаю это, запрос составляет семь секунд, но результаты дублируются для каждой команды.

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

какие индексы вы имеете на этой таблице? –

+0

трудно найти лучший запрос, если вы пишете только часть sql, не пишите определения таблиц и не пишите данные примера ... –

ответ

0

попробовать этот запрос:

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 
    /**/ 
Смежные вопросы