MySQL 3.23.49 DB-Performance

Hallo zusammen,

für eine PHP+MySql Webanwendung benutze ich MySql 3.23.49.

Im Firmennetzwerk liefert eine normale SQL-Abfrage über 6 Tabelle die 2000 Datensätze ins PHP-Frontend auch nicht sehr schnell ( ~ 7 sek. ).
Wenn ich aber vom aussen über z.b. www.meineanwendung.de zugreife, brauche ich sehr noch länger (fast 24 sek.), bis die 2000 Datensätze angezeigt werden.

In PHP-Code verwende ich immer nach $row = mysql_fetch_assoc($result);
mysql_free_result($result) also gebe immer den Speicher frei.

Tabellen sind vom Typ MyISAM, da die Version 3.23.49 installiert ist.

Wie kann ich die PERFORMANCE der Anwendung VERBESSERN (PHP und/oder MySql)?

Viele Dank,
Denis

Hallo!

Als erstes:

http://dev.mysql.com/doc/mysql/de/explain.html

Mit EXPLAIN kannst Du schauen, wo die meiste zeit verbrauchtw wird. Ich tippe zudem auf falsche oder inefiziente identifzierung / Aufbau der Select’s.
Kopier doch bitte mal den Tabellen Aufbau hierher (DESC ) und Deine SELECT’s.

Chris


www.schlechte-doku-hasser.de

Hallo Chris,

viele Dank für deine schnelle Antwort.

Der Aufbau der PHP-Seite ist sehr langsam bei 2000 Ergebnisse. Meine zusätliche Frage wäre: kann man, wenn man die Seite zum erstenmal aufruft, das MySql-Ergebniss in Session in einem Array speichern?

$results = array();

while ($row = mysql_fetch_array($admin, MYSQL_ASSOC)) {

$results[] = $row;

echo $row[„cd_name“] ." ";
echo $row[„cd_eschreibung“] usw …
}

$_SESSION[‚session_results‘] = $results;

Wie lese ich die Daten danach aus dem Array??

HIER DIE TABELLEN UND SELECT-QUERY:

CREATE TABLE sender_data (
sender_data_id int(11) NOT NULL auto_increment,
sender_id int(11) default ‚0‘,
cd_id int(11) NOT NULL default ‚0‘,
video_id int(11) default NULL,
kassette_id int(11) default NULL,
dvd_id int(11) default NULL,
sender_data_text text,
sender_data_kommentar text,
message_type_id int(11) default ‚0‘,
anzeigen enum(‚Y‘,‚N‘) default ‚Y‘,
PRIMARY KEY (sender_data_id),
UNIQUE KEY sender_data_id (sender_data_id),
KEY sender_id (kanal_id),
KEY cd_id`` (cd_id``),
KEY video_id (video_id),
KEY kassette_id (kassette_id),
KEY dvd_id (dvd_id),
KEY message_type_id (message_type_id)
) TYPE=MyISAM

CREATE TABLE sender (
sender_id int(11) NOT NULL auto_increment,
sender_name varchar(255) NOT NULL default ‚‘,
sender_beschreibung text,
PRIMARY KEY (sender_id),
UNIQUE KEY sender_id (sender_id)
) TYPE=MyISAM

CREATE TABLE cd (
cd_id int(11) NOT NULL auto_increment,
cd_name varchar(255) NOT NULL default ‚‘,
cd_beschreibung text NOT NULL,
cd_message_type int(11) NOT NULL default ‚0‘,
PRIMARY KEY (sender_id),
UNIQUE KEY sender_id (sender_id),
KEY message_type_id (cd_message_type)
) TYPE=MyISAM

CREATE TABLE message_type (
message_type_id int(11) NOT NULL auto_increment,
message_type_name varchar(255) NOT NULL default ‚‘,
PRIMARY KEY (message_type_id),
UNIQUE KEY message_type_id (message_type_id)
) TYPE=MyISAM

CREATE TABLE kassette (
kassette_id int(11) NOT NULL auto_increment,
kassette_name varchar(255) NOT NULL default ‚‘,
kassette_beschreibung varchar(255) NOT NULL default ‚‘,
PRIMARY KEY (kassette_id),
UNIQUE KEY kassette_id (kassette_id)
) TYPE=MyISAM

##############################################################

Die tabellen „video“ und „dvd“ sind z.b. genau so wie kassette (mit id, name, beschreibung).

Die MySQL-Abfrage:

SELECT
kc.sender_code_id,
kc.sender_id,
kc.cd_id,
kc.video_id,
kc.kassette_id,
kc.dvd_id,
kc.sender_code_text,
kc.sender_code_kommentar,
kc.anzeigen,
mt.message_type_name,
mc.cd_name,
v.kassette_name,
s.dvd_name,
f.video,
k.sender_id
FROM
sender_code kc
INNER JOIN sender k ON (kc.sender_id = k.sender_id)
INNER JOIN video f ON (kc.video_id = f.video_id)
INNER JOIN kassette v ON (kc.kassette_id = v.kassette_id)
INNER JOIN dvd s ON (kc.dvd_id = s.dvd_id)
INNER JOIN cd mc ON (kc.cd_id = mc.cd_id)
INNER JOIN message_type mt ON (mc.cd_message_type = mt.message_type_id) AND (kc.message_type_id = mt.message_type_id)
WHERE
(k.sender_id = ‚1‘)

###############################################################

Nach EXPLAIN SELECT …bekomme ich folgende Meldung:

table type possible_keys key key_len ref rows Extra
k const PRIMARY,sender_id PRIMARY 4 const 1
mc ALL PRIMARY,cd_id NULL NULL NULL 298
kc ref sender_id,cd_id,video_id,kassette_id,dvd_id cd_id 4 mc.cd_id 3 where used
v eq_ref PRIMARY,kassette_id PRIMARY 4 kc.kassette_id 1
f eq_ref PRIMARY,video_id PRIMARY 4 kc.video_id 1
s eq_ref PRIMARY,dvd_id PRIMARY 4 kc.dvd_id 1

mt eq_ref PRIMARY,message_type_id PRIMARY 4 kc.message_type_id 1

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hi Denis

viele Dank für deine schnelle Antwort.

No problem.

Der Aufbau der PHP-Seite ist sehr langsam bei 2000 Ergebnisse.

Huch. Dann vermute ich mal, das nicht die MySQL DB der Verursacher ist. Sondern schlicht das Netzwerk / WebServer. Die Seite muss ja erst „gebaut“ werden …

Meine zusätliche Frage wäre: kann man, wenn man die Seite zum
erstenmal aufruft, das MySql-Ergebniss in Session in einem
Array speichern?

Das macht MySQL von sich aus. Also wenn man immer das selbe SELECT Statement nutzt, wenn auch sich Parameterwerte in der WHERE Klasuel ändern - so chacht MySQL die Antwortmengen und baut Schlüßelbäume …

$results = array();

Also ich hab keinen Designfehler gesehen. Ist voll okay. Was Du machen könntest ist, Anhand der EXPLAIN Aussage die Nutzung der Schüßel mit Hand zu setzen. Also das Du vorschreibst: Bilde erst die Menge X und dann erst daraus Y. Steht in der Doku (und ich müßte auch erst nachgucken … das geht mit use key und force key.) Die Logig in der 4er werden besser gepuffert - soll heissen es wird optimiert, für NÄCHSTE Abfragen. Die MySQL 3er wurde optimiert für Erstzugriffe. Der Unterschied ist deutlich und kann sich echt verfielfachachen. Also bei solchen großen mengen, wo man weiß, welche Mengenmächtigkeiten ungefähr existieren …nachhelfen.

Ich tippe jedoch darauf, dass das Bauen und Versenden der HTML Tabs dann am längsten dauert.
Kannst Du nicht das SQL Statment mal OHNE Datenmenge Dir zusenden lassen?

Also so SELECT 1 FROM und dann Dein ganzes SQL Gedöns. Falls das auch ewig dauert isses die DB. Wenn nicht … Webserver angucken.

Was mir noch einfällt: Chachgröße des MySQL Readcaches vergrößern.

Chris


www.software-developers-home.de