2017-07-15 6 views
0

Ich habe eine MySQL-Tabelle mit der folgenden Konfiguration:MySQL Auswahlabfrage in Widen Tabellenoptimierung

CREATE TABLE `MONITORING` ( 
`REC_ID` int(20) NOT NULL AUTO_INCREMENT, 
`TIME` int(11) NOT NULL, 
`DEVICE_ID` varchar(30) COLLATE utf8_unicode_ci NOT NULL, 
`MON_ID` varchar(10) COLLATE utf8_unicode_ci NOT NULL, 
`TEMPERATURE` float NOT NULL, 
`HUMIDITY` float NOT NULL, 
PRIMARY KEY (`REC_ID`), 
KEY `SelectQueryIndex` (`TIME`,`MON_ID`)) 
ENGINE=MyISAM AUTO_INCREMENT=102069 DEFAULT CHARSET=utf8 
COLLATE=utf8_unicode_ci 

Mehrere Überwachungsgeräte Daten senden, immer genau auf die Minute, aber nicht alle Monitore sind immer online. Ich verwende PHP, um die Datenbank abzufragen und die Daten zu formatieren, um sie in ein Google Liniendiagramm zu übertragen.

Um die Daten in das Google Chart zu bekommen, führe ich eine SELECT-Abfrage aus, die die Ergebnisse mit allen MON_IDs in einer einzigen Zeile anzeigt.

Die Abfrage Ich bin derzeit mit ist:

SELECT `TIME`, `H5-C-T`, `P-C-T`, `H5-C-H`, `P-C-H`, `A-T`, `A-H` FROM 
    (SELECT `TIME`, `TEMPERATURE` as 'H5-C-T', `HUMIDITY` as 'H5-C-H' FROM `MONITORING` where `MON_ID` = 'H5-C') AS TAB_1, 
    (SELECT `TIME` as `TIME2`, `TEMPERATURE` as 'P-C-T', `HUMIDITY` as 'P-C-H' FROM `MONITORING` where `MON_ID` = 'P-C') AS TAB_2, 
    (SELECT `TIME` as `TIME3`, `TEMPERATURE` as 'A-T', `HUMIDITY` as 'A-H' FROM `MONITORING` where `MON_ID` = 'Ambient') AS TAB_3 
    WHERE TAB_1.TIME = TAB_2.TIME2 AND TAB_1.TIME = TAB_3.TIME3 

Die Ergebnisse sind genau das, was ich (Tabelle mit der Zeit und dann eine Temp und RH Spalte für jede der drei Monitore) wollen, aber scheint, wie die Abfrage dauert viel länger als es sollte, um die Ergebnisse zu geben.

Das Öffnen der gesamten Tabelle oder das Auswählen aller Zeilen von nur einem Überwachungsgerät dauert ca. 0,0006 Sekunden (kann nicht viel besser sein).

Wenn ich die Abfrage mit 2 der Überwachungsgeräte mache dauert es etwa 0,09 Sekunden (immer noch nicht schlecht, aber eine ziemlich große prozentuale Zunahme).

Wenn ich das dritte Überwachungsgerät einsetze, beträgt die Abfrage etwa 2,5 Sekunden (das ist jetzt in Ordnung, aber da mehr Daten gesammelt werden und mehr Geräte gleichzeitig in Charts sein müssen, ist es das übermäßig schnell werden).

Ich habe mir viele Posts angeschaut, in denen Leute versuchten, ihre Abfragen zu optimieren, aber konnten keine finden, die die Abfrage genauso machten wie ich (vielleicht mache ich es auf eine schlechte Art ...). Von den anderen Dingen, die Leute getan haben, um die Leistung zu verbessern, habe ich mehrere Indizierungsmethoden ausprobiert, sicher gestellt, die Tabelle in PHP MyAdmin zu prüfen, zu analysieren und zu optimieren, verschiedene andere Abfragemethoden auszuprobieren, Sortierfeld/Reihenfolge der Tabelle geändert, aber Ich war nicht in der Lage, einen anderen Weg zu finden, um die Ergebnisse zu bekommen, die ich schneller brauchte.

Meine Tabelle hat insgesamt etwas weniger als 100.000 Zeilen, und es scheint, als wären meine Abfragegeschwindigkeiten viel länger als erwartet, basierend auf den vielen Leuten, die Abfragen auf Tabellen mit Dutzenden von Millionen von Datensätzen ausgeführt haben.

Irgendwelche Empfehlungen auf eine Weise, meine Abfrage zu optimieren?

Vielleicht ist die Antwort so etwas wie mehrere MySQL-Abfragen und dann fügen Sie sie irgendwie in PHP zusammen (ich habe versucht, einen Weg zu finden, dies zu tun, aber konnte es nicht zum Laufen bringen)?

+0

Bitte geben Sie 'SHOW CREATE TABLE' für jede Tabelle an, damit wir Ihnen leichter helfen können. –

+0

Diese Art von Problem ist symptomatisch für schlechtes Design – Strawberry

+0

Rick, ich habe die SHOW CREATE TABLE hinzugefügt. Erdbeere, ich verstehe, dass ich vielleicht ein schlechtes Design habe, weshalb ich hier um Hilfe von hochqualifizierten Leuten frage. –

Antwort

0

Dinge umdrehen;

SELECT h.`TIME`, 
     h.TEMPERATURE AS 'H5-C-T', 
     p.TEMPERATURE AS 'P-C-T', 
     h.HUMIDITY AS 'H5-C-H', 
     p.HUMIDITY AS 'P-C-H', 
     a.TEMPERATURE AS 'A-T', 
     a.HUMIDITY AS 'A-H' 
    FROM MONITORING AS h 
    JOIN MONITORING AS p ON h.TIME = p.TIME 
    JOIN MONITORING AS a ON a.TIME = h.TIME 
    WHERE h.`MON_ID` = 'H5-C' 
     AND p.`MON_ID` = 'P-C' 
     AND a.`MON_ID` = 'Ambient' 

Und verwenden JOIN...ON Syntax: Leistung wird viel besser sein.

Ist die Kombination von TIME und REC_ID eindeutig? Wenn ja, wäre die Leistung noch besser, wenn Sie zu InnoDB wechseln, REC_ID loswerden und KEY SelectQueryIndex (TIME,MON_ID) in PRIMARY KEY(TIME, MON_ID) ändern würden.

Sie sollten auch in Erwägung ziehen, zu InnoDB zu wechseln.

+0

Vielen Dank Rick! Dadurch sank die Geschwindigkeit für die Abfrage auf 0,0012 für alle drei zusammen. –