2016-05-30 6 views
0

У меня есть система, которая собирает данные из производственных отчетов (CSV-файлов) и помещает их в базу данных mySql. У меня есть таблица заголовков, которая содержит производственные данные последовательного отчета с одинаковыми настройками и таблицу с единственными отчетами, связанную с первой (trfCamRep.hdrId -> trfCamHdr.id).Slow mySql update, содержащий Join

У меня есть запрос, чтобы рассчитать общий отчет, дубликат и неисправность, а также maxTs. Эти данные используются в визуализаторе.

Запрос выполняется слишком медленно, для этого требуется 9сек. Можете ли вы помочь мне ускорить его?

SET @maxId:=(SELECT MAX(id) FROM trfCamHdr WHERE srcCod='7'); 

UPDATE trfCamHdr AS hdr 
LEFT JOIN (SELECT hdrF.id,COUNT(*) AS nTot, 
    SUM(IF(res=1,1,0)) AS nWrn,SUM(IF(res=2,1,0)) AS nKO, 
     MAX(ts) AS maxTS 
    FROM trfCamHdr AS hdrF 
    JOIN trfCamRep AS repF ON repF.hdrId=hdrF.id 
    WHERE clcEnd=0 AND srcCod='7' 
    GROUP BY hdrF.id) AS valT ON valT.id=hdr.id 
SET hdr.clcEnd=IF(hdr.id<@maxId,1,0), 
    hdr.nTot=valT.nTot, 
    hdr.nWrn=valT.nWrn, 
    hdr.nKO=valT.nKO, 
    hdr.maxTS=valT.maxTS 
WHERE hdr.id>=0 AND hdr.clcEnd=0 AND hdr.srcCod='7'; 

Примечание trfCamHdr имеет следующие столбцы:

  • идентификатор (первичный ключ)
  • clcEnd: флаг расчета конца (последний остается 0, так как в процессе)
  • Ntot: элементы с этот заголовок
  • nWrn: элементы с res = 1
  • nKO: элементы с res = 2
  • maxTs: TS последнего элемента

trfCamRep имеет следующие столбцы:

  • hdrId (см идентификатор trfCamHdr)
  • Рез: 0 хорошие, 1 dubt, 2 вина
  • TS: отчет временной метки

ответ

0

я бы это:

SET @maxId:=(SELECT MAX(id) FROM trfCamHdr WHERE srcCod='7'); 

И любые намеки на переменную MaxId, я считаю, что это избыточно. Все, что вы делаете, будет ниже максимального id, и потребуется время, чтобы вычислить, есть ли его большая таблица. Вы уже проверяете srcCod = 7, поэтому это необязательно. На самом деле, он пропустит обновление на одном с фактическим максимальным id, что не так, как я полагаю, вы хотите.

Ваше левое соединение также обновит все остальные строки в таблице с помощью NULL, это то, что вы хотите? Вы можете переключить это на внутреннее соединение, и если ваши строки уже нулевые, они просто останутся одни, а не будут обновляться с помощью NULL.

Тогда можно просто перейти из этого:

SET 
    hdr.clcEnd = IF(hdr.id < @maxId, 1, 0), 

Для

SET 
    hdr.clcEnd = 1, 

Вот переписан вещь, как всегда, обратно ваши данные до, прежде чем пытаться:

UPDATE trfCamHdr AS hdr 
     INNER JOIN 
    (SELECT 
     hdrF.id, 
      COUNT(*) AS nTot, 
      SUM(IF(res = 1, 1, 0)) AS nWrn, 
      SUM(IF(res = 2, 1, 0)) AS nKO, 
      MAX(ts) AS maxTS 
    FROM 
     trfCamHdr AS hdrF 
    JOIN trfCamRep AS repF ON repF.hdrId = hdrF.id 
    WHERE 
     clcEnd = 0 AND srcCod = '7' 
    GROUP BY hdrF.id) AS valT ON valT.id = hdr.id 
SET 
    hdr.clcEnd = 1, 
    hdr.nTot = valT.nTot, 
    hdr.nWrn = valT.nWrn, 
    hdr.nKO = valT.nKO, 
    hdr.maxTS = valT.maxTS 
WHERE 
    hdr.id >= 0 AND hdr.clcEnd = 0 
     AND hdr.srcCod = '7'; 
+0

Благодарим вас за ответ.Если необходимо, чтобы обновить и последнюю строку. – user3227849

+0

Я хочу, чтобы они могли видеть последнюю строку, которая обновляется в реальном времени, когда создается новый отчет. – user3227849

0

Я нашел решение: я создал KEY на столбце hdrId и d теперь запрос требует 0.062s.