Warnung: file_put_contents(/home/www/web1/html/php_dev/test.txt) [function.file-put-contents]: failed to open stream: Permission denied in /home/www/web1/html/php_dev/sys/lib.activity.php (Zeile 58)
Performance Problem Php / Mysql [Archiv] - PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr
ebiz-webhosting
- Ad -
php-resource




Archiv verlassen und diese Seite im Standarddesign anzeigen :
Performance Problem Php / Mysql


 
HenLab
02-02-2004, 10:01 
 
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)

 
wahsaga
02-02-2004, 10:04 
 
ich verschieb's erstmal zu SQL.

 
HenLab
02-02-2004, 10:11 
 
...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 ;)

 
derHund
02-02-2004, 13:27 
 
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

 
HenLab
02-02-2004, 21:24 
 
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

 
derHund
02-02-2004, 22:04 
 
Original geschrieben von mrhappiness
*grml* :motz:


tralala :) gleich mal die url des motzer merken ...

 
Rocco
03-02-2004, 01:59 
 
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

 
HenLab
04-02-2004, 12:49 
 
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?

 
HenLab
04-02-2004, 16:00 
 
> 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?

 
HenLab
04-02-2004, 16:35 
 
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?

 
HenLab
04-02-2004, 16:54 
 
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

 
derHund
04-02-2004, 17:10 
 
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

 
HenLab
04-02-2004, 17:11 
 
bei mysql_num_rows sihet es genauso aus, wahrscheinlich braucht mysql einfach so lange.

 
HenLab
04-02-2004, 17:28 
 
mysql> select count(id) from artikel where kunden_id=654
-> ;
+-----------+
| count(id) |
+-----------+
| 1179309 |
+-----------+
1 row in set (2.66 sec)


Alle Zeitangaben in WEZ +2. Es ist jetzt 14:56 Uhr.