PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : schleife wird uebergangen. warum?



semmelbroesel
07-12-2002, 10:37
hi
ich hab einen algorithmus geschrieben der 2 mysql tabellen gleichzeitig abfragt und dann ein assoziatives array mit teilen aus beiden tabellen zurueckgibt.
mein problem ist, das bei folgendem code die innere while-schleife nur beim 1. durchlauf der aeusseren genutzt wird.
bei jedem weiteren durchlauf wird die innere schleife scheinbar ignoriert.

hier ist der code:


function show($theme_id)
{
global $MYSQL_DATA;
mysql_connect($MYSQL_DATA["con"]["host"],$MYSQL_DATA["con"]["user"],$MYSQL_DATA["con"]["pwd"]);
mysql_select_db($MYSQL_DATA["dbs"]["board"]);
if($theme_id == "all")
{
$query_themes = "SELECT id, title FROM themes ;";
}
else
{
$query_themes = "SELECT id, title FROM themes WHERE id=$theme_id;";
}
$query_categories = "SELECT id, theme_id, title FROM categories ";
$result_themes = mysql_query($query_themes);
$result_categories = mysql_query($query_categories);
if(mysql_num_rows($result_themes)>0)
{
$return = array();
$category = array();
$i = 0;
while($fetched_themes=mysql_fetch_object($result_t hemes))
{
$j = 0;
while($fetched_categories=mysql_fetch_object($resu lt_categories))
{
if($fetched_themes->id == $fetched_categories->theme_id)
{
$category[$j] = array(
"id"=>$fetched_categories->id,
"title"=>$fetched_categories->title
);
}

$j++;
}
if(count($category)==0)
{
$category = false;
}
$return[$i] = array(
"id"=>$fetched_themes->id,
"title"=>$fetched_themes->title,
"category"=> $category
);
$i++;
}
}
else
{
$return = mysql_errno().": ".mysql_error();
}
mysql_close();
return $return;
}

Gaert
07-12-2002, 17:11
Du musst

$result_categories = mysql_query($query_categories);
mit in die erste Schleife nehmen!

mehlvogel
09-12-2002, 09:20
Was natürlich eine erhebliche Erhöhung der Laufzeiot zur Folge hat. Ich würde versuchen das ganze in eine SQL Abfrage zu packen. Ich kenn die DB Struktur ja net, aber irgendwie so:



$query = "SELECT t.id, t.title, c.id, c.theme_id, c.title FROM themes AS t LEFT JOIN categories AS c ON c.theme_id=t.id";


Ich weis natürlich nicht, ob das Möglich ist, aber das würde denk ich auf jeden Fall die Laufzeit verringern.

semmelbroesel
09-12-2002, 13:14
hmm das ist leider bei der aktuellen struktur nicht möglich!
wieviel verbesserung wuerde das denn schaetzungsweise bringen?

mehlvogel
09-12-2002, 14:20
Es kommt natürlich darauf an, was und wieviel dort in der Datenbank steht. Prinzipiell ist es besser sowenig wie möglich Anfragen an die Datenbank zu schicken, weil dies (meiner Erfahrung nach) einer der langsamsten Stellen am System ist. Also sollte man die Anfragenzahl so stark begrenzen wie möglich.

In Zahlen kann ich es nicht ausdrücken. Nach betitelung der Datenbanken würde ich fast auf ein Forensystem tippen was dort programmiert wird (oder etwas ähnliches) und dort können schnell einige MB zusammenkommen - dann ist die Einsparung erheblich. Aber auch bei Lowendanwendungen, sollte man denk ich drauf achten. Schätzen würd ich je anch Umfang der Tabellen, Datenbank, etc zwischen 10 - 20% (weis vielleicht irgendwer genaue Zahlen)

Ansonsten schreib dir nen kleinen Timer, der dir die Zeiten pro SQL Befehl oder die Runtime ausgibt. Dann kannst du vergleichen wieviel sich ändert - man sollte aber dran denken das schon die vierte Stelle nach dem Komma ne Zahl ist, um die man kämpfen sollte ;)

semmelbroesel
09-12-2002, 15:48
will ich gern mal machen!
mit forensystem liegst du ziemlich richtig.

das problem ist halt bei eben dieser funktion brauch ich
alle felder aus der themes tabelle und alle felder aus der categories tabelle
da jedem eintrag der themes tabelle mindestens ein eintrag der categories tabelle zu geordnet wird.
wenn deine anfrage das kann wunderbar, aber ich hab bisher noch nicht rausgefunden wie. denn bei mir liefert si nur die eintraege aus der categories tabelle zurueck. oder ich sprechs falsch an.

mehlvogel
09-12-2002, 16:02
Die Frage ist, hängen die beiden Abfragen zusammen? Denn zur Zeit (wenn du das in der while Schleife machst) - hast du in der Funktion genau "Anzahl der Reihen in themes" + 1 Abfragen. Was bei großer Themes DB natürlich zu ewig vielen Abfragen hinausläuft.

sowie ich es sehe sind die über das eine Feld verknüpft - deshalb hatte ich es in der ON Bedingung übernommen. Vielleicht musst du meinen SELECT Befehl von eben ein wenig modifizieren:



$query_=_"SELECT t.id AS themes_id, t.title AS themes_title,
c.id AS categories_id,
c.theme_id AS categories_theme_id,
c.title AS categories_title___
FROM themes AS t
LEFT JOIN categories AS c ON c.theme_id=t.id";


Und dann den Array den du bekommst - auf die Elemente mit




$arr["categories_id"] ...


zugreifen. Vielleicht so?

semmelbroesel
10-12-2002, 12:11
tut mir leid aber das versteh ich nicht so ganz.
kannst du mal einen kurzen beispiel code posten?(ganze funktion)

mehlvogel
10-12-2002, 12:46
function show($theme_id)
{
global $MYSQL_DATA;
mysql_connect($MYSQL_DATA["con"]["host"],$MYSQL_DATA["con"]["user"],$MYSQL_DATA["con"]["pwd"]);
mysql_select_db($MYSQL_DATA["dbs"]["board"]);
if($theme_id == "all")
$query_themes = "SELECT t.id AS themes_id, t.title AS themes_title,
c.id AS categories_id,
c.theme_id AS categories_theme_id,
c.title AS categories_title
FROM themes AS t
LEFT JOIN categories AS c ON c.theme_id=t.id";
else
$query_themes = "SELECT t.id AS themes_id, t.title AS themes_title,
c.id AS categories_id,
c.theme_id AS categories_theme_id,
c.title AS categories_title
FROM themes AS t
LEFT JOIN categories AS c ON c.theme_id=t.id WHERE id=$theme_id;";

$result_themes = mysql_query($query);
if(mysql_num_rows($result_themes)>0)
{
$return = array();
$category = array();
$i = 0;
while($fetched_themes=mysql_fetch_object($result_t hemes))
{
// Was du halt damit tun willst...
array_push($return, $fetched_themes);
}
else
{
$return = mysql_errno().": ".mysql_error();
}
mysql_close();
return $return;
}