[PHP/MYSQL] Performance ?

resoucer

Gesperrt
ID: 77379
L
20 April 2006
2.846
109
Hi, wollte mal anfragen was ihr für die performanceschonende möglichkeit haltet folgendes zu bewerbstelligen:

PHP:
 function passwort ($laenge) 
{ 
$abc ="a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,0,1,2,3,4,5,6,7,8,9"; 
$abcarray = explode(",",$abc); 
mt_srand((double)microtime()*1000000); 
$daspasswort = ""; 
for ($i=1;$i<=$laenge;$i++) 
{ 
$zufall = mt_rand(0,Count($abcarray)); 
$daspasswort .= $abcarray[$zufall]; 
} 
return str_replace(" ","",$daspasswort); 
} 


$zahl=1;
do  {
 $pw=passwort(10); 
 $tb2 = mysql_query("SELECT id FROM `".$tb_prefix."PPWW` WHERE `pw` ='$pw'"); 
 $zahl=mysql_num_rows($tb2);
} while (1 < $zahl);

Also ich brauche ein PW welches noch nicht vergeben wird, sozusagen eine eindeutig identifizierbare id.

Problem ist das es etwa 100.000 Einträge enthält und ~jede sek. ausgeführt wird.
 
da es bei einer Länge von 5 Zeichen und 59 mögliche Chars 71.4924.299 versch. Möglichkeiten gibt, sind Kollisionen relativ selten womit deine Methode wahrscheinlich am ehesten zu empfehlen ist, nur bitte ein SELECT COUNT verwenden, denn dann ist die abfrage deutlich schneller, und die gameids in einer extra tabelle speichern um den overhead beim lesen der Tabelle zu sparen, also eine extra tabelle nach dem muster:
Code:
Game-Id | Code
1 | RTfg3
2 | 7GHg5
3 | 4GHZ6
4 | h67UIj

dabei wird auf schon existierende Game-IDs in dieser Tabelle überprüft, speichern tust du in der Log-Tabelle dann nur die wahre auto_increnment id
 
^^ okay,
was mir aber leider noch aufgefallen ist das manchmal (obwohl es eigentlich nicht sein dürfte)

2x die gleiche gameid generiert wird.
Als ob meine while schleife nicht richtig funzen würde

und

PHP:
$tb2 = mysql_query("SELECT Count(*) as zahl FROM `".$tb_prefix."PPWW` WHERE `pw` = '$pw'"); 
$row=mysql_fetch_row($tb2);
$zahl= $row[0];
} while (1 < $zahl);
ist besser?
 
Zuletzt bearbeitet:
deine Schleife ist sowieso falsch, denn sie soll so lange laufen wie die Anzahl der Ergebniszeilen größer als 1 ist, das bedeutet aber, wenn sie genau 1 ist, erzeugst du eine Kollision ;)
vllt solltest du lieber schreiben while($zahl>0)
 
PHP:
$zufall = mt_rand(0,Count($abcarray));  
$daspasswort .= $abcarray[$zufall];
array_rand() ist hier wohl besser.
PHP:
return str_replace(" ","",$daspasswort);
Wieso Leerzeichen entfernen, wenn gar keins reinkommen kann ? ;)

Zum Problem selber möchte ich eine Alternative in den Raum werfen, die vermutlich schneller sein könnte, weil man ja nicht wirklich viele Kollisionen erwartet:
Da die IDs eh in einer MySQL-Datenbank gespeichert werden, kannst du doch
PHP:
do {
  $pw=password(10);
  mysql_query("INSERT IGNORE INTO table (field) VALUES ('$pw')");
} while(mysql_affected_rows()!=1);
machen und das Feld PRIMARY/UNIQUE-indizieren.
Für Leute, die an alles denken und im Falle einer defekten Tabelle etc. keine Endlosschleife haben wollen, sollte der mysql_query()-Aufruf auf Fehler überprüft werden.

Vorteil des Ganzen: Falls keine Kollision auftritt (was wohl in 99,999% der Fälle sein wird), ist keine Mehrbelastung der Datenbank erforderlich.