Wollte mal allgemein fragen, wie man den Code verbessern kann, sodass die Geschwindigkeit um einiges steigt? Hoffe Ihr habt da Ideen.
mfg
Verbesserung des Codes
gepostet vor 18 Jahre, 1 Monat von forsti222
gepostet vor 18 Jahre, 1 Monat von progs
gepostet vor 18 Jahre, 1 Monat von meisterjoda
hier im forum oder bei google nach scriptoptimierung für php scripte suchen
ich hab das vor einiger zeit auch gemacht. das was am meisten geschwindigkeitsgewinn bringt, ist alle datenbankabfragen so gestalten, dass so wenige abfragen wie möglich gemacht werden, denn das braucht am meisten geschwindigkeit. wenn du beispielsweise eine db-abfrage hast, und in der ergebnisschleife wird nochmal was anderes abgefragt, dann macht es mehr sinn, vorher die daten aus der anderen abfrage in einen array zu laden und dann damit zu arbeiten.
kleines beispiel:
anstatt
$result=mysql_query("SELECT id,name,allianz FROM user ORDER BY name",$db);
while ($myrow = mysql_fetch_row($result)) {
$res2=mysql_query("SELECT name FROM allianz_main WHERE id='$myrow[2]'",$db);
while ($row= mysql_fetch_row($res2)) {
$allianz=$row[0];
}
echo "$myrow[1] ist in $allianz
";
}
schreibst du es lieber so
$result=mysql_query("SELECT id,name FROM allianz_main ORDER BY name",$db);
while ($myrow = mysql_fetch_row($result)) {
$allianz[$myrow[0]]=$myrow[1];
}
$result=mysql_query("SELECT id,name,allianz FROM user ORDER BY name",$db);
while ($myrow = mysql_fetch_row($result)) {
echo "$myrow[1] ist in ".$allianz[$myrow[2]]."
";
}
dadurch sparst du ne menge sql-abfragen. wenn bspw. 100 user gelistet werden, hast du im ersten beispiel 1+100=101 db-abfragen, im zweiten beispiel genau 2 abfragen.
ich hab das vor einiger zeit auch gemacht. das was am meisten geschwindigkeitsgewinn bringt, ist alle datenbankabfragen so gestalten, dass so wenige abfragen wie möglich gemacht werden, denn das braucht am meisten geschwindigkeit. wenn du beispielsweise eine db-abfrage hast, und in der ergebnisschleife wird nochmal was anderes abgefragt, dann macht es mehr sinn, vorher die daten aus der anderen abfrage in einen array zu laden und dann damit zu arbeiten.
kleines beispiel:
anstatt
$result=mysql_query("SELECT id,name,allianz FROM user ORDER BY name",$db);
while ($myrow = mysql_fetch_row($result)) {
$res2=mysql_query("SELECT name FROM allianz_main WHERE id='$myrow[2]'",$db);
while ($row= mysql_fetch_row($res2)) {
$allianz=$row[0];
}
echo "$myrow[1] ist in $allianz
";
}
schreibst du es lieber so
$result=mysql_query("SELECT id,name FROM allianz_main ORDER BY name",$db);
while ($myrow = mysql_fetch_row($result)) {
$allianz[$myrow[0]]=$myrow[1];
}
$result=mysql_query("SELECT id,name,allianz FROM user ORDER BY name",$db);
while ($myrow = mysql_fetch_row($result)) {
echo "$myrow[1] ist in ".$allianz[$myrow[2]]."
";
}
dadurch sparst du ne menge sql-abfragen. wenn bspw. 100 user gelistet werden, hast du im ersten beispiel 1+100=101 db-abfragen, im zweiten beispiel genau 2 abfragen.
gepostet vor 18 Jahre, 1 Monat von Benj
ist das nicht noch besser??
$sql='SELECT a.name as ally, b.name as name FROM allianz_main a, user b WHERE b.allianz=a.id ORDER BY name';
$result=mysql_query($sql ,$db);
while ($myrow = mysql_fetch_row($result)) {
echo $myrow[1].' ist in '.$myrow[0].'
';
}
$sql='SELECT a.name as ally, b.name as name FROM allianz_main a, user b WHERE b.allianz=a.id ORDER BY name';
$result=mysql_query($sql ,$db);
while ($myrow = mysql_fetch_row($result)) {
echo $myrow[1].' ist in '.$myrow[0].'
';
}
gepostet vor 18 Jahre, 1 Monat von progs
Generell sind JOINs schneller als zwei Abfragen (zwei SELECTS). Genau kann man das aber nie sagen, kommt immer mit auf die Daten drauf an. Mit EPLAIN kann man sich Infos zum Select anzeigen lassen und ggf. optimieren.
dev.mysql.com/doc/refman/5.1/de/explain.html
dev.mysql.com/doc/refman/5.1/de/explain.html
gepostet vor 18 Jahre, 1 Monat von Tetha
Imo sollte man gar nicht soooviel in die Optimierung von PHP-Scripten stecken, solange die im Bereich des linearen Aufwandes liegen und normalerweise eine konstante Anzahl von Abfragen an die Datenbank schicken...
Ich meine, wen interresiert bitte, dass der reine PHP-code nun nur 356 ns statt 380 ns laeuft, wenn dagegen die Datenbankabfrage Zeit im Millisekundenbereich liegt, ganz zu schweigen von der Uebertragung uebers Netz...
Imo bringt es da mehr, die Queries mittels EXPLAIN genauer unter die Lupe zu nehmen und die Datenbank so zu trimmen, dass man pro Query mit ca 2-4 Joins auskommt, wobei diese alle in den oberen Performance-schichten rangieren sollten.
Wenn das gut laeuft, kann das PHP da drumherum nicht mehr viel kaputtmachen, ausser es soll langsam sein.
MfG
Ich meine, wen interresiert bitte, dass der reine PHP-code nun nur 356 ns statt 380 ns laeuft, wenn dagegen die Datenbankabfrage Zeit im Millisekundenbereich liegt, ganz zu schweigen von der Uebertragung uebers Netz...
Imo bringt es da mehr, die Queries mittels EXPLAIN genauer unter die Lupe zu nehmen und die Datenbank so zu trimmen, dass man pro Query mit ca 2-4 Joins auskommt, wobei diese alle in den oberen Performance-schichten rangieren sollten.
Wenn das gut laeuft, kann das PHP da drumherum nicht mehr viel kaputtmachen, ausser es soll langsam sein.
MfG
gepostet vor 18 Jahre, 1 Monat von None
Wenn es um Performance geht, dann muß man ab und an die Normalisierungsregeln vergessen.
Was ich auch teilweise schon gemacht habe, war das ich alle Daten per fetch_array () aus dem RecordSet ausgelesen habe und diese dann nur noch in PHP verarbeite.
Ist oftmals um EINIGES schneller als die gleichen Operationen in MySQL.
Oder beim Update von großen Datenmengen...
Transaktionen nutzen, Indizies rauswerfen...
Indizies kosten enorm Zeit beim Updaten/Inserten.
Was ich auch teilweise schon gemacht habe, war das ich alle Daten per fetch_array () aus dem RecordSet ausgelesen habe und diese dann nur noch in PHP verarbeite.
Ist oftmals um EINIGES schneller als die gleichen Operationen in MySQL.
Oder beim Update von großen Datenmengen...
Transaktionen nutzen, Indizies rauswerfen...
Indizies kosten enorm Zeit beim Updaten/Inserten.
gepostet vor 18 Jahre, 1 Monat von Drezil
kommt daraf an, wie man seine syntax schreibt ..
ich hab schon performence boosts von 80% gehabt, nur weil ich die reihenfolge im "from-teil" umgestellt habe. so wurde nämlich über join und where nen cross-join von 2050x10 Datensätze auf 10x50 Datensätze reduziert.
man muss (insbesondere bei komplizierten anfragen) sich das explain einfach genau zu gemüte führen.
ich häng mal nen etwas "komplexeres" beispiel aus meinem sql-log an (die qry hatte ne effektive rechenzeit von wenigen ms [lt. mysql-query-browser 92.9ms + 24ms zum ausliefern des ergebnisses - kein benchmark, server war auch nicht wirklich unter last]).
ok .. anhang geht nicht .. dan eben hier:
ifnull(uf.stufe,0) as stufe,fn.name_de as name
from forschungsreferenz f
join forschungsreferenznamen fn on (f.fid=fn.fid)
left outer join forschungen uf on (uf.fid = f.fid)
left outer join forschtodo t on (f.fid = t.fid && t.uid='1'),
user_vorraussetzung u
where u.uid='1' &&
u.forsch1 & f.forsch1 = f.forsch1 &&
u.forsch2 & f.forsch2 = f.forsch2 &&
u.forsch3 & f.forsch3 = f.forsch3 &&
u.forsch4 & f.forsch4 = f.forsch4 &&
(CASE floor(f.fid / 64) +1 WHEN 1 THEN u.forsch1 WHEN 2 THEN u.forsch2
WHEN 3 THEN u.forsch3 WHEN 4 THEN u.forsch4 ELSE 0
END & 1 << MOD(f.fid,64) = 0 || f.endlos = 1) &&
ifnull(uf.uid,'1') = '1'
order by f.typ,
fn.name_de asc
ist nur nen einfaches beispiel..
das explain dazu:
1, 'SIMPLE', 'u', 'const', 'PRIMARY', 'PRIMARY', 4, 'const', 1, 'Using temporary; Using filesort'
1, 'SIMPLE', 'fn', 'ALL', 'PRIMARY', '', , '', 100, ''
1, 'SIMPLE', 'f', 'eq_ref', 'PRIMARY', 'PRIMARY', 8, 'mu.fn.fid', 1, 'Using where'
1, 'SIMPLE', 'uf', 'eq_ref', 'PRIMARY', 'PRIMARY', 8, 'mu.f.fid', 1, 'Using where'
1, 'SIMPLE', 't', 'eq_ref', 'PRIMARY', 'PRIMARY', 16, 'mu.f.fid,const', 1, ''
von normalisierungen vergessen halte ich nicht viel. dass lieber ein paar redundante einträge auf häufige rechenlastige qrys (vllt. auch ne haep-table) und dann jede nacht einen abgleich dieser mit den "echten" daten.
edit: was die abfrage oben noch beschleunigen würde wär ne 64-bit-cpu .. die abfrage macht nämlich binäroperationen auf 64-bit-ints .. und zwar 4 pro eingeführter forschung..
ich hab schon performence boosts von 80% gehabt, nur weil ich die reihenfolge im "from-teil" umgestellt habe. so wurde nämlich über join und where nen cross-join von 2050x10 Datensätze auf 10x50 Datensätze reduziert.
man muss (insbesondere bei komplizierten anfragen) sich das explain einfach genau zu gemüte führen.
ich häng mal nen etwas "komplexeres" beispiel aus meinem sql-log an (die qry hatte ne effektive rechenzeit von wenigen ms [lt. mysql-query-browser 92.9ms + 24ms zum ausliefern des ergebnisses - kein benchmark, server war auch nicht wirklich unter last]).
ok .. anhang geht nicht .. dan eben hier:
select ifnull(t.fpforsch,0) as fpforsch,f.fid,f.fp,f.typ,f.endlos,
ifnull(uf.stufe,0) as stufe,fn.name_de as name
from forschungsreferenz f
join forschungsreferenznamen fn on (f.fid=fn.fid)
left outer join forschungen uf on (uf.fid = f.fid)
left outer join forschtodo t on (f.fid = t.fid && t.uid='1'),
user_vorraussetzung u
where u.uid='1' &&
u.forsch1 & f.forsch1 = f.forsch1 &&
u.forsch2 & f.forsch2 = f.forsch2 &&
u.forsch3 & f.forsch3 = f.forsch3 &&
u.forsch4 & f.forsch4 = f.forsch4 &&
(CASE floor(f.fid / 64) +1 WHEN 1 THEN u.forsch1 WHEN 2 THEN u.forsch2
WHEN 3 THEN u.forsch3 WHEN 4 THEN u.forsch4 ELSE 0
END & 1 << MOD(f.fid,64) = 0 || f.endlos = 1) &&
ifnull(uf.uid,'1') = '1'
order by f.typ,
fn.name_de asc
ist nur nen einfaches beispiel..
das explain dazu:
id, select_type, table. type, possible_keys, key, key_len, ref, rows, Extra
1, 'SIMPLE', 'u', 'const', 'PRIMARY', 'PRIMARY', 4, 'const', 1, 'Using temporary; Using filesort'
1, 'SIMPLE', 'fn', 'ALL', 'PRIMARY', '', , '', 100, ''
1, 'SIMPLE', 'f', 'eq_ref', 'PRIMARY', 'PRIMARY', 8, 'mu.fn.fid', 1, 'Using where'
1, 'SIMPLE', 'uf', 'eq_ref', 'PRIMARY', 'PRIMARY', 8, 'mu.f.fid', 1, 'Using where'
1, 'SIMPLE', 't', 'eq_ref', 'PRIMARY', 'PRIMARY', 16, 'mu.f.fid,const', 1, ''
von normalisierungen vergessen halte ich nicht viel. dass lieber ein paar redundante einträge auf häufige rechenlastige qrys (vllt. auch ne haep-table) und dann jede nacht einen abgleich dieser mit den "echten" daten.
edit: was die abfrage oben noch beschleunigen würde wär ne 64-bit-cpu .. die abfrage macht nämlich binäroperationen auf 64-bit-ints .. und zwar 4 pro eingeführter forschung..
gepostet vor 18 Jahre, 1 Monat von Fornax
Wie ist eigentlich der Perfomanceunterschied zwischen den mysql_* Funktionen und dem neuem mysqli?
gepostet vor 18 Jahre, 1 Monat von progs
Folgenden Artikel hab ich dazu gefunden und sollte eigentlich ganz interessant sein: devzone.zend.com/node/view/id/686