Hallo,
ich habe einen relativ einfaches Statement:
SELECT id FROM messages WHERE area = '8' ORDER BY id DESC LIMIT 1
Mit 100.000 Datensätzen dauert das 8 Sekunden. Mit 10.000 Datensätzen nur 0.2 Sekunden. Wie kann das sein? Eigentlich sollte MySQL mit steigender Anzahl von Datensätzen doch nicht langsamer werden.
Der Server hat genug Speicher und sowohl auf id als auch auf area liegen index-Tabellen.
Ich habe keine Idee, welche Ansätze ich verfolgen kann, um dem Problem auf die Spur zu kommen.
Für jeden Ansatz bin ich dankbar.
Oli.
hmm 8 sekunden ist irgendwie zu lang..
welchen typ hat das feld area?
Das Feld ist ein varchar mit der Länge 4. Eine Area kann auch Buchstaben beinhalten.
mhm. schon komisch.
welches spalten hast du noch drin? poste bitte mal die komplette struktur.
Schau' Dir mal an was
DESCRIBE SELECT id FROM messages WHERE area = '8' ORDER BY id DESC LIMIT 1
ausgibt ...
CREATE TABLE messages (
id int(11) NOT NULL auto_increment,
area varchar(4) NOT NULL default '',
parent int(11) NOT NULL default '0',
datetime datetime NOT NULL default '0000-00-00 00:00:00',
host varchar(64) default NULL,
author varchar(255) NOT NULL default '',
subject varchar(255) NOT NULL default '',
body text,
approved char(1) default NULL,
PRIMARY KEY (id),
KEY area(area),
KEY parent (parent),
KEY approved (approved),
KEY datetime (datetime),
) TYPE=MyISAM;
denke zwar nicht, dass es daran liegt, aber man sollte keine feldnamen so wählen, dass es zweideutig ist.
feld datetime vom typ datetime ist nicht gut. :teach:
verwende da mal den namen dateandtime besser.
hast du schon goth's sache gemacht?
Die Ausgabe von
DESCRIBE SELECT id FROM messages WHERE area = '8' ORDER BY id DESC LIMIT 1
ist:
Array
(
[0] => messages
[1] => range
[2] => area
[3] => area
[4] => 4
[5] =>
[6] => 87479
[7] => where used; Using filesort
)
Moment... über die Konsole ist der Output viel schöner:
+----------------+-------+---------------+-------+---------+------+-------+----------------------------+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+----------------+-------+---------------+-------+---------+------+-------+----------------------------+
| messages | range | area | area | 4 | NULL | 87479 | where used; Using filesort |
+----------------+-------+---------------+-------+---------+------+-------+----------------------------+
wenn ich das richtig sehe, liefert dir die abfrage insgesamt 87479 datensätze zurück bei denen die area = 8 ist .
kann man das nicht noch einschränken, sodass es weniger daten sind, und dadurch schneller?
du stellt ja bestimmt nicht alle daten auf einmal dar, oder?
ein LIMIT sollte da was helfen.
Ich habe doch die Anzahl der Datensätze bereits mit LIMIT 1 eingeschränkt. Ich habe die MySQL-Doku so verstanden, dass die Datenbank 87479 "anfassen" muß, um meinen gesuchten Datensatz zu finden. Im Resultset ist definitiv nur ein Datensatz vorhanden.
so wie ich das sehe, sortierst Du Dein Resultset absteigend, sprich im Endeffekt hast Du die größte Id, bei der die Are = 8 ist.
Vielleicht ist ein max() schneller?
SELECT MAX(id) FROM messages WHERE area = '8'