Archiv verlassen und diese Seite im Standarddesign anzeigen : Performance Problem Php / Mysql
Hallo,
wir haben in den letzten Monaten mit PHP und MySQL einen elektronischen Teilekatalog programmiert. Die Software arbeitet mit bis zu 50.000 Artikeln problemlos. Leider haben wir am Wochenende festgestellt, dass mit erwarteteten 500.000 - bis 2 Mio. Artikelen die ganze Anwendung zu stehen scheint. Dauert allles bis ca. 5 Minuten. Wir haben schon einige primary-keys, indizies, uniques etc. definiert, aber null Erfahrung, ob das so richtig ist.
Da wir noch keine Erfahrungen mit so einem Problem haben, wüsste ich gerne wo wir mit der Optimierung anfangen könten. Sollten wir am Besten die einezelnen PHP Scripte überprüfen und optimieren, oder ist das Problem eher bei MySQL zu suchen? Ist es wohl wahrscheinlicher, dass unterschiedliche PHP Abfragen die Performance runter ziehen, oder sind solche Einbußen eher mit einer Indexierung von Datenbanken zu beheben? Ich weiss, das 2 Miollionen Positionen für MySQl eigentlich kein Problem sind, leider haben wir aber keine Erfahrung in der Datenbankoptimierung.
Unsere ersten Tests haben gezeigt, dass schon eine reine Suche über 2 Spalten unsere Performance fast stehen lässt.
Vielen Dank für jede Antwort und jeden Hinweis zur Optimierung.
Happy Nihilist 02-02-2004, 10:03 Ich glaube, das wäre eher was für das Brainstorming-Forum!
(Ich glaube, ich wäre ein gute Moderator =P)
ich verschieb's erstmal zu SQL.
...aha, danke. eine frage haben ich noch, gibt es tools welche mir die performance von php / mysql prozessen darstellen können. antworten auf o.g. frage bitte nicht vergessen.
schmalle 02-02-2004, 11:16 Original geschrieben von Happy Nihilist
(Ich glaube, ich wäre ein gute Moderator =P) ist das ne bewerbung? :)
Happy Nihilist 02-02-2004, 11:18 Original geschrieben von schmalle
ist das ne bewerbung? :)
Ich bewerbe mich nicht - ich lasse mich anheuern ;)
hmm,
du könntest ja spaßes halber ein paar deiner queries posten, wir könnten drüber diskutieren, ...
dings ( ;) ) hat letztens auch ne klasse hier im forum veröffentlicht, zum performance messe, vielleicht hilft das ja auch ....
DaGuertliz 02-02-2004, 21:14 http://www.phphq.de/mysql.de/manual.de_289.html
mrhappiness 02-02-2004, 21:17 Original geschrieben von derHund
hdings*grml* :motz:
abgesehen von den äußerungen des gemeinen fußvolks hier ;) solltest du uns deine datenbankstrukturmitteilen und die abfragen, die du absetzt
da lässt sich vielleichtnoch das ein oder andere quentchen geschwindigkeit rausholen
ok, erstmal danke für die ganzen antworten. ich weiß gar nicht genau mit welchem code ich anfangen soll. ich poste mal eine wenig. kann ich kit phpmyadmin die datenbank struktur auseleden?
<?
session_cache_limiter('nocache');
session_start();
include_once("../db/db.inc.php");
include_once("../lib/array.countries.php");
include_once("../lib/functions.php");
include_once("../lib/class.FormData.php");
include_once("../lib/class.System.php");
include_once("../lib/class.Zone.php");
include_once("../lib/class.Tarif.php");
include_once("../lib/class.Kunde.php");
include_once("../lib/class.Kundenoptionen.php");
include_once("../lib/class.Artikel.php");
include_once("../lib/class.Suchbegriff.php");
include_once("../lib/class.Bestellung.php");
set_time_limit(1200000);
define("DEBUG_VARS", FALSE);
//echo "<hr>Session ID: ".session_id()."<hr>";
//________________________________________________________________________
//
// System gesperrt => Seite mit Meldung (kein Login moeglich)
//________________________________________________________________________
$system = new System();
$system->read_db_current_state();
if($system->status != "aktiv")
{
session_unset();
session_destroy();
include("pages/system.view.php");
exit(0);
}
//________________________________________________________________________
//
// Bei jedem Request ausser beim Einloggen ...
//________________________________________________________________________
if($action != "login")
{
//____________________________________________________________________
//
// Unauthorisierter Zugriff => Login-Seite
//____________________________________________________________________
if(!session_is_registered("user"))
{
//echo "manual logout<br>";
session_unset();
session_destroy();
include("pages/login.form.php");
exit(0);
}
//________________________________________________________________________
//
// Authorisierter Zugriff =>
// automatischer Logout <timeout> Sekunden nach letztem Request
// oder Zeitpunkt des neuen letzten Request des Kunden in DB speichern
//________________________________________________________________________
if(session_is_registered("user"))
{
$query = "SELECT time_last_request FROM kunden";
$query.= " WHERE id='".$user->id."'";
$result = mysql_query($query);
$db_obj = mysql_fetch_object($result);
$time_last_request = $db_obj->time_last_request;
if($time_last_request != 0
&& $time_last_request < time() - REQUEST_TIMEOUT)
{
//echo "auto logout<br>";
session_unset();
session_destroy();
$error = "Aus Sicherheitsgründen wurden Sie automatisch abgemeldet.<br>Bitte melden Sie sich aus Sicherheitsgründen erneut an.";
include("pages/login.form.php");
exit(0);
}
else
{
// neuen letzten Request-Zeitpunkt in DB schreiben
//echo "request at ".time()."<br>";
$kunde = new Kunde();
$kunde->read_db($user->id);
$kunde->time_last_request = time();
$kunde->update_db();
}
}
}
//________________________________________________________________________
//
// 'register_globals = On' simulieren und Formulardaten in String schreiben
//________________________________________________________________________
$form_vars= basename($PHP_SELF)."<br>";
if(isset($_GET['action']))
{
$form_vars_array =& $_GET;
}
else if(isset($_POST['action']))
{
$form_vars_array =& $_POST;
}
if(isset($form_vars_array))
{
foreach($form_vars_array as $var=>$val)
{
${$var} = $val;
$form_vars .= $var." => ".$val."<br>";
}
}
$sess_vars = "";
foreach($_SESSION as $var=>$val)
{
$sess_vars .= $var." => ".$val."<br>";
}
$debug_vars = $form_vars."<br>".$sess_vars;
?>
mrhappiness 02-02-2004, 21:26 mich interessiert primär wie deine datenbank aussieht
welche tabellen hast du?
was speicherst du wo?
primärschlüssel?
...?
als zweites kommen dann die sql-anfragen
kannst mir auch, wenn du willst, die daten zu deinem phpmyadmin geben
Original geschrieben von mrhappiness
*grml* :motz:
tralala :) gleich mal die url des motzer merken ...
Wie soll uns denn dieser Code nuetzen den du da gepostet hast? ;)
Schreib mal hier den Query rein der eine 5-Minuten-Last erzeugt sowie die DB-Struktur der betroffenden Rows.
Benutzt ihr auch nur einen einzigen Join-Befehl in euren SQL-Abfragen? Da wohl Produktdaten über mehrere Tabellen verteilt sind und gegebenfalls oft querselektiert wird, sind fehlende Joins in solchen Angelegenheiten schonmal ein potentielles Problem.
kannst mir auch, wenn du willst, die daten zu deinem phpmyadmin geben
Da freut sich der Kunde sicher drüber... ;)
Rocco
ok, dann poste mal eine abfrage, in der datenbank sind momentan 1,5 Millionen Einträge, Index habe ich schon einige probiert :-( . Die Abfrage dauert bis ca. 12 Sekunden) - 2 Sec. wären wünschenswert.
table structure:
id(primary key), id2, id3, name, kunden_id
query = SELECT COUNT(id) FROM artikel WHERE kunden_id='654'
gibt es an der abfrage noch etwas zu optimieren, oder gibt es eine schnellere trickreiche methode? die datenbank struktur ist leider nicht zu ändern.
danke für eure hinweise.
mrhappiness 04-02-2004, 15:53 is auf kunden_id ein index gelegt?
is das wirklich ein string oder ein integer-wert?
> is auf kunden_id ein index gelegt?
ja, habe ich gemacht.
> is das wirklich ein string oder ein integer-wert
die kunden id ist ein integer-wert.
mrhappiness 04-02-2004, 16:21 dann solltest du auch kunde_id=654 und nicht kunde_id='654' schreiben
wird dir aber trotzdem nicht wirklich mehr geschwindigkeit bringen
dauert die abfrage 12 sekunden in der konsole?
nach dem setzten des index nur noch ca. 4 sec. in der konsole. ein normales select ohne count nur 0.0010. gibt es alternativen zu count? ich bin mit meinem latein langsam am ende.
mrhappiness 04-02-2004, 16:49 ein select ohne count?
SELECT id FROM artikel WHERE kunden_id=654
so?
ja, ganau so 0,0009 sekunden
SQL-Befehl
SQL-Befehl :
EXPLAIN SELECT ID FROM artikel WHERE kunden_id =654
table type possible_keys key key_len ref rows Extra
artikel ALL kunden_id NULL NULL NULL 1179309 where used
hmm,
wenn sich durch den einsatz von count die ausführungszeit ver-100.000-facht ( :confused: ), laß daß count weg und nimm mysql_num_rows :rolleyes: .... obwohl ich mir das irgendwie nicht vorstellen kann
bei mysql_num_rows sihet es genauso aus, wahrscheinlich braucht mysql einfach so lange.
mysql> select count(id) from artikel where kunden_id=654
-> ;
+-----------+
| count(id) |
+-----------+
| 1179309 |
+-----------+
1 row in set (2.66 sec)
|
|