2016-11-20 1 views
1

Könnten Sie mir bitte im Folgenden helfen?MySQL/löschen von/Warum ist es so langsam?

Der MySQL-Befehl unten läuft über 4 Sekunden auf einem modernen PC, wo nichts anderes ausgeführt wird, auch wenn mehrmals ausgeführt:

DELETE FROM table1 
WHERE column1 LIKE 'pattern1%' AND 
     column2 IN (SELECT column3 FROM table2 WHERE column4 = 'pattern2') 

tabelle1 enthält ca.. 1100 Datensätze, von denen 95% mit Spalte1/Muster1% übereinstimmen. ca.

table2 enthält. 5000 davon, die nahe Null sind, stimmen mit column4/pattern2 überein.

Host: MySQL v5.7, Ubuntu 16 64 bit, schneller SSD, mem InnoDB Pool ist 1 GB

es in einem einfacheren oder schnelleren Weg machen kann? Vielen Dank.

Abfrage-Plan:

+----+--------------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+ 
| id | select_type  | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra  | 
+----+--------------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+ 
| 1 | DELETE    | table1 | NULL  | ALL | NULL   | NULL | NULL | NULL | 1179 | 100.00 | Using where | 
| 2 | DEPENDENT SUBQUERY | table2 | NULL  | ALL | NULL   | NULL | NULL | NULL | 4601 |  1.00 | Using where | 
+----+--------------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+ 
+0

Bitte zeigen Sie den Abfrageplan –

+1

sind column1 und column2 indiziert? Können Sie uns den create table-Code für table1 anzeigen? – barudo

+0

Anders als Indizes sieht diese Abfrage für mich ziemlich optimal aus. Bitte versuchen Sie es mit EXPLAIN. –

Antwort

1

Es hängt von der Größe Ihrer Tabellen und Ihre Indizes Konfiguration.

Zum Beispiel, wenn Tabelle2 nicht zu groß ist, ordnungsgemäß von Spalte4 indiziert, und das Ergebnis der Subselect ist auch nicht groß, können Sie die Reihenfolge der Bedingungen umkehren, so dass die column2-Bedingung zuerst ausgeführt wird, und wenn es nicht tut Wenn keine Übereinstimmung gefunden wird, wird die Ausführung der möglicherweise langsameren column1-ähnlichen Abfrage nicht gestört.

DELETE FROM table1 
WHERE column2 IN (SELECT column3 FROM table2 WHERE column4 = 'pattern2') AND 
     column1 LIKE 'pattern1%' 
+0

Danke, ich werde es an einem Tag testen und das Ergebnis schreiben. – log69

+0

Wie in dem Abfrageplan gezeigt, gibt es keinen Index für Spalte 4. Das muss wirklich da sein, um gute Leistung zu erhalten. – Arjan

+0

@Arjan: Ich werde es mit einem Index überprüfen, obwohl das EXPLAIN keine Beschleunigung mit einem Index zeigt, wie ich sehe. – log69

0

Sie müssen Indizes hinzufügen, um Ihre Abfrage zu beschleunigen. Zumindest sollte es einen Index auf column 4 in table 2. Wahrscheinlich möchten Sie einen kombinierten Index für (column 4, column3) erstellen.

Da Sie zeigen, dass etwa 95% aller Reihen in table 1 Match auf column 1 gibt in dem Hinzufügen eines Index für column 1 wirklich keinen Sinn. Wenn die Anzahl der Übereinstimmungen für column 2 relativ klein ist, können Sie einen Index für diese Spalte hinzufügen.

+0

Ich wollte keine Indizes verwenden, da sich diese Tabellen ständig und schnell ändern (jede Minute). – log69

+0

Wenn Sie viele Insert-Abfragen ausführen, sollten Sie die Anzahl der Indizes niedrig halten. Für andere Abfragen benötigen Sie jedoch einige Indizes, auf die Sie in diesem Fall nicht verzichten können. – Arjan

1

Es scheint aus der EXPLAIN Abfrage, die Ihre Tabelle (n) nicht richtig eingestellt Indizes hat. Indizes werden verwendet, um Zeilen mit bestimmten Spaltenwerten schnell zu finden.

Einer der wichtigsten Verwendung von Leistungsperspektive von Indizes ist die Zeilen zu finden eine WHERE Klausel schnell entsprechen. Ohne Index MySQL muss mit der ersten Zeile beginnen und dann durch die gesamte Tabelle lesen die entsprechenden Zeilen zu finden. Je größer der Tisch, desto mehr kostet das. Wenn die Tabelle einen Index für die fraglichen Spalten enthält, kann MySQL schnell die Position ermitteln, die in der Mitte der Datendatei gesucht werden soll, ohne alle Daten betrachten zu müssen. Dies ist viel schneller als das sequentielle Lesen jeder Zeile.

0

Ich habe es gelöst schließlich durch einen Index table2/column3 hinzufügen. Danke Jeder für Ihre Hilfe.