Ich habe eine gespeicherte Prozedur wie folgt deklariert:
%Vor%Wenn ich die Verwendung des Parameters dom_id durch eine statische Ganzzahl ersetze, zB:
%Vor%MySQL-Version: 5.5.41
ERKLÄREN:
%Vor%SHOW CREATE TABLE-Domäne:
%Vor%Die Prozedur dauert 0,06s, um ausgeführt zu werden, während der Parameter "dom_id" verwendet wird und den Integer-Wert von 1 übergibt, führt dies zu einer Ausführungszeit von 5.070s. Irgendwelche Ideen?
Wie bei der Frage möchte @sboss das Verhalten von:
kennen %Vor%Dieses Verhalten kann leicht verstanden werden, wenn wir sehen, wie die mysql-Engine funktioniert.
MySQL Engine speichert Abfrage und Ergebnis zwischen. Der Abfrage-Cache speichert den Text einer SELECT-Anweisung zusammen mit dem entsprechenden Ergebnis, das war an den Kunden gesendet. Wenn später eine identische Aussage erhalten wird, Server ruft die Ergebnisse aus dem Abfrage-Cache ab, statt zu analysieren und die Anweisung erneut ausführen.
Daher ist es in Ihrem Fall höchstwahrscheinlich, dass execution time of 5.070s
gefunden wird, wenn die Abfrage tatsächlich von der MySQL-Engine analysiert und ausgeführt wird und execution time of 0.06s
gefunden wird, wenn die Ergebnismenge aus dem Abfrage-Cache abgerufen wurde.
Bitte lesen Sie die Dokumentation für Details: Ссылка
Optimierung 1
Teil der Verlangsamung ist die wiederholt ausgeführte "abhängige Unterabfrage":
%Vor% Gemäß EXPLAIN
müssen alle ~ 8703 Zeilen von link
jedes Mal gescannt werden.
Ich glaube nicht, dass es innerhalb derselben Abfrage vereinfacht werden kann. Stattdessen denke ich, dass dies nützlich sein wird:
%Vor%Dann
%Vor% Sie können testen, ob der PREPARE
-Ansatz schneller ist. In einem (einfacheren) Test, den ich gemacht habe, schien das keine Rolle zu spielen.
Optimierung 2
Eine andere potenzielle Beschleunigung besteht darin, die GROUP_CONCATs
in Unterabfragen anstatt des Sammelns von vielen Zeilen durchzuführen und dann zu kollabieren. Beachten Sie, dass Sie GROUP BY
verwenden mussten. Diese Technik kann dies möglicherweise beseitigen. Zum Beispiel:
- & gt;
%Vor%Der Grund, warum möglicherweise ist, kann beobachtet werden, wenn Sie dies sowohl mit Ihrer Variante als auch mit meiner Variante tun:
%Vor% Ihre Variante wird (unter der Annahme vieler Kategorien usw.) einen viel größeren COUNT
haben. Das bedeutet, dass Ihre Abfrage eine viel größere Tabelle erstellt, um sie an GROUP BY
und ORDER BY
zu füttern. Daher langsamer.
Optimierung 3
Wenn Sie alle Aggregate ( GROUP_CONCAT
) loswerden, dann sollten Sie INDEX(country, name)
weiter optimieren, indem Sie die beiden FILESORTs
loswerden.
Sie sagen hier, dass Sie die Daten schnell abrufen können, während Sie WHERE verwenden Domänen.land = 1 Anstatt von WOHER domain.country = dom_id aber ich bin nicht in der Lage, where-Klausel auf domain.country in Ihrer Abfrage zu sehen. Kannst du das bitte klären?
Aber im Allgemeinen ist was passiert
Bitte lassen Sie mich wissen, wenn Sie nach etwas anderem suchen.
Löschen Sie zuerst Ihre Zweifel, warum die Abfrage Zeit braucht, wenn Sie den Wert über Parameter übergeben. Da Rick und Jaydatt in ihren Beiträgen erwähnt haben, dass der Cache abgefragt werden kann, können Sie diese Zweifel zunächst beheben, indem Sie Ihre Abfrage mit dem Zusatz SQL_NO_CACHE wie SELECT SQL_NO_CACHE domain.id, IFNULL(domain.indexed, '-') AS indexed,....
Ich denke, jetzt solltest du ca. Gleichzeitig durch beide Abfragen.
Auch für die Optimierung dieser Abfrage hat Rick Ihnen so viele nützliche Optionen zur Verfügung gestellt, dass Sie die untenstehende Option auch zusammen mit diesen überprüfen können.
Überprüfen Sie zuerst, ob das Feld link.from_domain indiziert ist oder nicht, da explain zeigt, dass alle Zeilen aus der Linktabelle scannen.
Sie können auch die Abfrageleistung mit folgendem Ansatz überprüfen:
%Vor%Tags und Links mysql performance stored-procedures parameters left-join