Wir aktualisieren unsere DB-Systeme auf MySQL 5.7 aus MySQL 5.6 und seit dem Upgrade ein paar Abfragen wurden sehr langsam ausgeführt.MySQL JOIN Filterung auf WHERE-Klausel mit < > Operatoren seit Umzug von MySQL 5.6 -> 5.7
Nach einigen Nachforschungen haben wir es auf ein paar JOIN-Abfragen beschränkt, die plötzlich die 'WHERE' Klausel nicht mehr hören, wenn ein 'größer als'> oder 'kleiner als' < Operator verwendet wird. Wenn Sie einen '=' Operator verwenden, funktioniert es wie erwartet. Bei der Abfrage einer großen Tabelle führte dies zu einer konstanten CPU-Auslastung von 100%.
Die Abfragen wurden vereinfacht, um das Problem zu erklären; bei der Verwendung erklären wir die folgenden Ausgaben erhalten:
explain
select * from TableA as A
left join
(
select
DATE_FORMAT(created_at,'%H:%i:00') as `time`
FROM
TableB
WHERE
created_at < DATE_ADD(CURDATE(), INTERVAL -3 HOUR)
)
as V ON V.time = A.time
Ausgabe
Wie Sie sehen können, ist es die Abfrage/488.389 Reihen passend und nicht mit der where-Klausel, da dies die Gesamt ist Datensätze in dieser Tabelle.
Und jetzt die gleiche Abfrage, aber mit einem LIMIT 99999999 Befehl oder mit dem '=' Operator ausgeführt wird:
explain
select * from TableA as A
left join
(
select
DATE_FORMAT(created_at,'%H:%i:00') as `time`
FROM
TableB
WHERE
created_at < DATE_ADD(CURDATE(), INTERVAL -3 HOUR) LIMIT 999999999
)
as V ON V.time = A.time
Ausgabe
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 PRIMARY A NULL ALL NULL NULL NULL NULL 10080 100.00 NULL
1 PRIMARY <derived2> NULL ALL NULL NULL NULL NULL 244194 100.00 Using where; Using join buffer (Block Nested Loop)
2 DERIVED TableB NULL range created_at created_at 4 NULL 244194 100.00 Using where; Using index
Sie können es sehen, nur plötzlich zusammenbringt '244194' Zeilen, die ein Teil der Tabelle ist, oder mit dem '=' Operator:
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE A NULL ALL NULL NULL NULL NULL 10080 100.00 NULL
1 SIMPLE TableB NULL ref created_at created_at 4 const 1 100.00 Using where; Using index
Nur 1 Reihe, wie erwartet.
So ist die Frage jetzt ist, haben wir in einer falschen Weise wurde die Abfrage und jetzt nur noch herauszufinden, während oder haben Dinge da 5.6 MySQL geändert Upgrade? Es scheint seltsam, dass der = Operator funktioniert, aber die < und > sind aus irgendeinem Grunde ignoriert, es sei denn, wenn ein LIMIT? ..
Wir um gesucht haben und könnten die nicht gefunden Ursache dieses Problems, und wir verwenden die Lösung 9999999 Limit aus offensichtlichen Gründen lieber nicht in unserem Code.
Hinweis Wenn nur die Abfrage in der Verknüpfung ausgeführt wird, funktioniert es wie erwartet.
Hinweis Wir haben auch den gleichen Test auf MariaDB 10.1 ausgeführt, dasselbe Problem.
Haben Sie die Indizes aktualisiert? Es behauptet, den Index zu verwenden, – Kickstart
Ja, Indizes sind vorhanden und aktualisiert auf die Felder in Frage – Nick