Ich habe Leistungsprobleme bei bestimmten Datenbankabfragen mit möglicherweise großen Ergebnismengen.
Bei der fraglichen Abfrage habe ich drei AND
s in der WHERE-Klausel
Ist die Reihenfolge der Klauseln wichtig?
Wie in, wenn ich die ASI_EVENT_TIME-Klausel an die erste Stelle setze (da dies die meisten Ergebnisse aus den Klauseln entfernen würde).
Verbessert dies die Laufzeit der Abfrage?
ABFRAGE:
SELECT DISTINCT activity_seismo_info.*
FROM `activity_seismo_info`
WHERE
activity_seismo_info.ASI_ACTIVITY_ID IS NOT NULL AND
activity_seismo_info.ASI_SEISMO_ID IN (43,44,...,259) AND
(
activity_seismo_info.ASI_EVENT_TIME>='2011-03-10 00:00:00' AND
activity_seismo_info.ASI_EVENT_TIME<='2011-03-17 23:59:59'
)
ORDER BY activity_seismo_info.ASI_EVENT_TIME DESC
Erklärung der Abfrage:
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
| 1 | SIMPLE | act...o | range | act...o_FI_1,act...o_FI_2 | act...o_FI_1 | 5 | NULL | 65412 | Using where; Using filesort |
+----+-------------+---------+-------+---------------------------+--------------+---------+------+-------+-----------------------------+
Verwenden von:
PHP 5.2
MySQL 5.0.51a-3ubuntu5.4
Antrieb 1.3
Symfony 1.2.5
mysql
performance
mysql-5
Patrick
quelle
quelle
order by
gehört in die Datenbank.Antworten:
Das glaube ich nicht. Das Abfrageoptimierungsprogramm sollte clever genug sein.
Sie können versuchen, die WHERE-Klauseln neu anzuordnen, und sehen, dass EXPLAINS Ihnen dies jeweils mitteilt.
Informationen zur Optimierung dieser Abfrage: Gibt es einen Index für ASI_EVENT_TIME? (Dies ist meiner Meinung nach das Entscheidendste für diese Abfrage, da Sie auch die Ergebnisse danach sortieren).
Gibt es Indizes für die anderen beiden Felder (ASI_SEISMO_ID und ASI_ACTIVITY_ID)?
Es wäre hilfreich, wenn Sie die Tabellenstruktur posten würden.
quelle
Aus der Dokumentation :
Also ja, es sollte die gleiche Reihenfolge wie die Spalten in einem zusammengesetzten Index haben .
quelle
WHERE c = 'foo' AND a = 'bar' AND b = 'foobar'
der Index weiterhin zur Verwendung berechtigt.Nein, das spielt keine Rolle.
Der Optimierer führt eine Reihe einfacher Transformationen durch, nachdem er die SQL analysiert hat - dies ist eine davon.
quelle
optimiert das selbe wie
Jedoch,
Beide Teile können nicht optimiert werden. Beispielsweise,
kann INDEX (a, b) oder INDEX (b, a) nicht gut gebrauchen
Um es anders auszudrücken, werden zuerst alle '=' Tests verwendet, die in der WHERE-Klausel UND-verknüpft sind. Dann kann ein Nicht-'=' (IN, BETWEEN,>, etc) behandelt werden. Nicht mehr als einer kann effektiv optimiert werden.
Ihre Anfrage enthält 3 solche Klauseln.
Wie sich herausstellt, ist INDEX (EVENT_TIME) wahrscheinlich das nützlichste - es hilft bei einem der ANDs und kann verwendet werden, um "filesort" für ORDER BY zu vermeiden.
Wenn es keine doppelten Zeilen gibt (warum zum Teufel würde es da sein?), Dann werde DISTINCT los. Das verursacht noch mehr Aufwand.
Bitte geben Sie SHOW CREATE TABLE und SHOW TABLE STATUS an, wenn Sie Fragen zur Leistung stellen.
Update ... Neuere Versionen (z. B. MySQL 5.7) können in einigen Situationen
IN( list of constants )
fast so behandelt werden=
. Um auf Nummer sicher zu gehen, halten Sie sich an diese Reihenfolge (jeder Teil ist optional):=
.INs
.quelle
MySQL, wo Optimierungsdokument sagt:
Auf diese Weise ist es sinnvoll, dass der Abfrageoptimierer die WIE-Reihenfolge weglässt, in der wir die Spalten in der Abfrage verwendet haben (Nicht nur MySQL, sondern auch SQL ist eine deklarative Sprache und muss tun, was wir wollen, nicht wie wir wollen).
Ich mag es immer noch, die gleiche Sortierung für die Spalten eines zusammengesetzten Schlüssels in der Abfrage zu haben, aber es ist manchmal unvermeidlich, wenn wir beispielsweise ORM oder ActiveRecord verwenden. In einigen Frameworks wie yii2 wird das Anpassen der Beziehungskriterien an das Ende von angehängt eine "Ein" -Zustand, aber wir benötigen immer noch die Funktionen von QueryBuilders in verschiedenen Teilen einer Anwendung.
quelle
JEDES Feld, das in Ihren WHERE / HAVING-Klauseln verwendet wird und eine hohe Selektivität aufweist (die Anzahl der eindeutigen Werte / die Gesamtzahl der Datensätze> 10% ~ 20%), MUSS indiziert werden.
Wenn Ihre
ASI_EVENT_TIME
Spalte also viele mögliche Werte enthält, indizieren Sie sie zuerst alle. Versuchen Sie dann, wie @ypercube sagte, sie neu anzuordnen und sehen Sie, was EXPLAIN Ihnen sagt. Sollte in etwa gleich sein.Darüber hinaus möchten Sie einen Blick auf die Indizierung von SQL LIKE-Filtern werfen . Es ist zwar nicht das, worauf Sie eine Antwort benötigen, aber Sie werden trotzdem lernen, wie die Indizierung unter der Haube funktioniert.
* Bearbeiten: Weitere Informationen zur Indizierung finden Sie in den Kommentaren unter den unten angegebenen Links.
quelle