Betrachten Sie eine Tabelle mit Werten und Hashes wie folgt:
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| val | char(9) | NO | | NULL | |
| val_hashed | char(50) | YES | | NULL | |
+------------+----------+------+-----+---------+----------------+
Die folgende Abfrage wird in 0,00 Sekunden beendet:
SELECT * FROM hashes ORDER BY 1 DESC LIMIT 1;
Diese Abfrage dauert jedoch 3 Minuten und 17 Sekunden:
SELECT val FROM hashes ORDER BY 1 DESC LIMIT 1;
Ich sehe, dass die Prozessliste den Status anzeigt, während die Abfrage ausgeführt wird Sorting result
. Die Situation ist vollständig reproduzierbar. Beachten Sie, dass ein anderer Prozess INSERT
kontinuierlich Vorgänge in der Tabelle ausführt .
Warum würde die Ausführung der spezifischeren Abfrage länger dauern als die *
Abfrage? Ich war immer der Meinung, dass *
Abfragen aus Performancegründen vermieden werden sollten.
mysql
performance
select
dotancohen
quelle
quelle
id
, um die erste Zeile zu finden. Der zweite muss das komplette Ergebnis in der (nicht indizierten)val
Spalte sortieren .ORDER BY NUMBER
Syntax ist sehr fehleranfällig.SELECT *
Kombination mit einem Spaltenindex inORDER BY
verschleiert, welche Spalte sortiert wird - ein weiterer Grund,*
s ...*
ist nicht explizit. Das Sprichwort "Gib mir alle Spalten und sortiere nach der dritten" ist ungefähr so deterministisch wie das Sprichwort "Geh in den Supermarkt und sag mir, wie viele Ampeln du passiert hast"Antworten:
Die Phrase
ORDER BY 1
bezieht sich auf verschiedene Spalten; im ersten wird es seinid
, im zweitenval
. Daid
es sich um den Schlüssel handelt, wird er indiziert, undorder by
dies ist ein geringfügiger Arbeitsaufwand. Umorder by val
jedoch jede Zeile abzurufen, muss das System die gesamte Tabelle nach sortierenval
und dann nur eine dieser Zeilen auswählen.Ändern Sie beide Abfragen in
order by id
und ich denke, Ihre Ausführungszeiten werden fast identisch sein.quelle
Der Leistungsunterschied in Ihrer Abfrage wird von MG gut erklärt. Ich werde folgendes ansprechen:
select *
trägt von sich aus keine besonderen Strafen, es ist problematisch bei Missbrauch. In einer Single-Table-Abfrage funktioniert es einwandfrei. Verbinden Sie nun diese Tabelle mit einer anderen mit 20 Spalten und fügen Sie später Verknüpfungen mit 5 anderen Tabellen mit jeweils vielen Spalten hinzu. JETZT ist es ein Problem. So sind es auch Leute, die breit gefächertes Pflaster lehren, "nie X machen", ohne zu erklären warum.quelle
SELECT *
Dies kann selbst bei einer Abfrage mit nur einer Tabelle ein Problem sein. Zum BeispielSELECT * FROM hashes ORDER BY val;
wird wahrscheinlich eine vollständige Tabellensuche und dann eine Sortierung durchgeführt, währendSELECT val FROM hashes ORDER BY val;
nur eine vollständige Indexsuche und keine Sortierung durchgeführt wird (vorausgesetzt, es existiert ein Index für val). Es tut also nie weh, nur die Ergebnisse auszuwählen, die wir brauchen.select(*)
nur als Unterauswahl verwendet wird? Wäre MySQL nicht klug genug, um die tatsächlichen Spalten zu ermitteln, die ausgewählt werden müssen, da es sich um eine eingebettete Auswahl handelt?