2016-05-30 11 views
0

Ich habe ein System, das Daten von Produktionsreports (CSV-Dateien) sammelt und sie in eine mySql DB legt. Ich habe eine Header-Tabelle, die die Produktionsdaten des sequentiellen Berichts mit der gleichen Einstellung enthalten, und eine Tabelle mit den einzelnen Berichten, die mit dem ersten verbunden sind (trfCamRep.hdrId -> trfCamHdr.id).Verlangsamen mySql-Update mit Join

Ich habe eine Abfrage, um den Gesamtbericht, den Dubt und die fehlerhaften und die maxTs zu berechnen. Diese Daten werden im Visualizer verwendet.

Die Abfrage ist zu langsam, es dauert 9 Sekunden. Können Sie mir helfen, es zu beschleunigen?

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'; 

Hinweis trfCamHdr hat folgende Spalten:

  • id (Primärschlüssel)
  • clcEnd: flag von End-Berechnung (die letzte, weil in Fortschritte auf 0 bleiben)
  • Ntot: Elemente mit diese Überschrift
  • nWrn: Elemente mit Res = 1
  • nKO: Elemente mit Res = 2
  • maxTs: TS des letzten Elements

trfCamRep hat folgende Spalten:

  • hdrId (siehe id von trfCamHdr)
  • res: 0 gut, 1 Sicherlich gehören, 2 Störung
  • ts: Bericht Zeitstempel

Antwort

0

ich würde nehmen diese heraus:

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

Und alle Anspielungen auf die Variable MaxId, ich glaube, dass es überflüssig ist. Alles, was Sie tun, wird niedriger als die maximale ID sein, und es wird Zeit brauchen, um zu berechnen, ob es ein großer Tisch ist. Sie suchen bereits nach srcCod = 7, also ist es nicht notwendig. In der Tat würde es das Update auf dem einen mit der tatsächlichen Max-ID verpassen, die nicht das ist, was ich glaube, dass Sie wollen.

Ihr linker Join wird auch alle anderen Zeilen in der Tabelle mit NULL aktualisieren, ist das was Sie wollen? Sie könnten das zu einem inneren Join wechseln, und wenn Ihre Zeilen bereits null sind, werden sie nur in Ruhe gelassen, anstatt wieder mit NULL aktualisiert zu werden.

Dann könnten Sie einfach das Gerät, das:

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

Um

SET 
    hdr.clcEnd = 1, 

Hier ist die neu geschrieben, was, wie immer, zurück Ihre Daten, bevor Sie versuchen:

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

Vielen Dank für die Antwort.Das if wird benötigt, um auch die letzte Zeile zu aktualisieren. – user3227849

+0

Ich möchte, dass sie die letzte Zeile sehen können, die in Echtzeit aktualisiert wird, wenn ein neuer Bericht erstellt wird. – user3227849

0

Ich habe die Lösung gefunden: Ich habe eine KEY auf hdrId Spalte erstellt d Jetzt erfordert die Abfrage 0,062s.