[php,sql] c-plusplus.de forum index schneller machen



  • Vielleicht es mit ein paar Indizes probieren?



  • Welche Datenbank habt ihr eigentlich?



  • Erstmal ne Frage:
    Was bezweckst Du mit

    while( $row = $db->sql_fetchrow($result) ) 
        { 
            if($row['topic_last_post_id'] != $last_topic_id || $row['topic_last_post_id'] == 0) 
            { 
                $last_topic_id = $row['topic_last_post_id']; 
                $forum_data[] = $row; 
            } 
        }
    

    Warum liest Du das ganze dann überhaupt aus der DB. wenn Du es eh wieder eliminierst?

    Und nun noch ein paar Anmerkungen:
    1. Schmeiß die komplette DB-Layer-Unterscheidung raus! Du verwendest wahrscheinlich eh nur ein einziges DBMS, also kannst Du die komplette DB-Klasse ersetzen.
    2. Entferne alle großen Kommentar-Blöcke. Der verursachte Overhead bei der Ladezeit ist bei großen Projekten durchaus relevant.
    3. Deine Zensurfunktion lässt sich wahrscheinlich auch noch optimieren. Wenn ich richtig rate, dann liefert Dir obtain_word_list() doch einen Satz verschiedener regulärer Ausdrücke, diese könntest Du jedoch in einem einzigen zusammenfassen und somit einen leichten Performance-Gewinn herausholen.
    4. Fasse Deine SQL-Queries in Hochkommata und nicht in Anführungszeichen.
    5. Ich bin jetzt mit dem Source des zugrunde liegenden Board-Systems nicht so vertraut, aber der gepostete Teil erweckt den Eindruck, daß man das Array $forum_data evtl. komplett eliminieren kann. Prüfe das doch mal nach.

    Gruß Jens



  • ah, gleich schon viel schneller 🙂



  • Marc++us schrieb:

    Also, ich denke die Datenbankabfrage -hat- das Potential.

    da hilft mir mein c++ wissen nicht weiter 😞

    Unregistrierter schrieb:

    Ich hab keine Ahnung von PHP, aber ist es nicht möglich, dass das "last-topic" nicht bei jedem Seitenaufruf, sondern konstant alle 3 Sekunden berechnet wird?

    das ist in php nicht so leicht möglich, außerdem wahrscheinlich langsammer

    Unregistrierter schrieb:

    Nimm den Mod raus und guck ob es besser wird 🙂

    ja leider

    O'Dog schrieb:

    Vielleicht es mit ein paar Indizes probieren?

    was ist das?

    O'Dog schrieb:

    Welche Datenbank habt ihr eigentlich?

    mysql 3.xx

    Sa(n)dman schrieb:

    Erstmal ne Frage:
    Was bezweckst Du mit

    while( $row = $db->sql_fetchrow($result) ) 
        { 
            if($row['topic_last_post_id'] != $last_topic_id || $row['topic_last_post_id'] == 0) 
            { 
                $last_topic_id = $row['topic_last_post_id']; 
                $forum_data[] = $row; 
            } 
        }
    

    ab und zu kommt ein daten satz doppelt im row vor (wahrscheinlich falscher sql code, aber ich müsste mich dann doch mehr mit sql befassen)

    Warum liest Du das ganze dann überhaupt aus der DB. wenn Du es eh wieder eliminierst?

    was meinst du

    Und nun noch ein paar Anmerkungen:
    1. Schmeiß die komplette DB-Layer-Unterscheidung raus! Du verwendest wahrscheinlich eh nur ein einziges DBMS, also kannst Du die komplette DB-Klasse ersetzen.

    finde ich nicht gut

    2. Entferne alle großen Kommentar-Blöcke. Der verursachte Overhead bei der Ladezeit ist bei großen Projekten durchaus relevant.

    so viel komentare sind da nicht drin

    3. Deine Zensurfunktion lässt sich wahrscheinlich auch noch optimieren. Wenn ich richtig rate, dann liefert Dir obtain_word_list() doch einen Satz verschiedener regulärer Ausdrücke, diese könntest Du jedoch in einem einzigen zusammenfassen und somit einen leichten Performance-Gewinn herausholen.

    ja aber dann kann ich alles nur zu eins umwandeln, es soll aber z.b. standart in standard umwandeln

    4. Fasse Deine SQL-Queries in Hochkommata und nicht in Anführungszeichen.

    ich will erstmal die high-level optimierung machen

    5. Ich bin jetzt mit dem Source des zugrunde liegenden Board-Systems nicht so vertraut, aber der gepostete Teil erweckt den Eindruck, daß man das Array $forum_data evtl. komplett eliminieren kann. Prüfe das doch mal nach.

    wenn ich wollte könnte ich ja das forum hardcoden in den php dateien 🙂 finde ich aber nicht so toll, denke nicht das man forum_data killen kann



  • Dimah schrieb:

    O'Dog schrieb:

    Vielleicht es mit ein paar Indizes probieren?

    was ist das?

    Der Plural von Index 🙂

    http://www.mysql.com/doc/en/MySQL_indexes.html

    Bringt 'ne Menge auf Spalten worüber Tabellen ge-joined werden oder auch einfach nur bei Abfragen von Spalten-Werten...wenn die Tabellen viele Sätze haben



  • ich verstehe nicht ganz wo das problem ist. jetzt wo du es rausgenommen hast, stehen doch auch Benutzername, Datum und Uhrzeit unter "Letzter Beitrag". Da wird es doch wohl kein Problem sein auch den Topic-Namen mitzuspeichern



  • Anonymous schrieb:

    ich verstehe nicht ganz wo das problem ist. jetzt wo du es rausgenommen hast, stehen doch auch Benutzername, Datum und Uhrzeit unter "Letzter Beitrag". Da wird es doch wohl kein Problem sein auch den Topic-Namen mitzuspeichern

    ohne den code und die db strucktur des phpbbs zu verändern?



  • Hast du schonmal probiert die Reihenfolge der einzelnen JOINs zu verändern - könnte evtl. schon etwas bringen (siehe dazu auch das hier)


  • Mod

    der phpbb code scheint mir ein graus zu sein...

    ich wuerde es brutal machen:

    eine neue tabelle erstellen die exakt soviele eintraege hat wie wir foren.
    bei jedem neuen posting wird brutal ein update ausgefuehrt unnd setzt in dieser tabelle den titel des letzten postings.
    da kannst du uhrzeit und user id auch dazu geben, dann bist du extrem schnell, da du mit einem query alles bekommst.

    allerdings musst du dann die struktur aendern, was sich aber IMHO auszahlt. denn ich wuesste nicht wie man es anders effektiv schaffen koennte.



  • Shade Of Mine schrieb:

    der phpbb code scheint mir ein graus zu sein...

    ich wuerde es brutal machen:

    eine neue tabelle erstellen die exakt soviele eintraege hat wie wir foren.
    bei jedem neuen posting wird brutal ein update ausgefuehrt unnd setzt in dieser tabelle den titel des letzten postings.
    da kannst du uhrzeit und user id auch dazu geben, dann bist du extrem schnell, da du mit einem query alles bekommst.

    allerdings musst du dann die struktur aendern, was sich aber IMHO auszahlt. denn ich wuesste nicht wie man es anders effektiv schaffen koennte.

    ungern, denn das bedeutet viele eingriffe in den orginal code, was sich negativ beim updaten auswirkt



  • Sollten doch nur 2 Eingriffe sein? Einmal dort wo Posting in Empfang genommen wird und einmal auf der Index-Seite.

    Man muss ja nicht unbedingt eine Datenbank nehmen. Für jedes Forum eine eigene Textdatei sollte doch auch gehen, oder?

    Also z.B. f_1.txt:

    ie starten
    abcqurz
    16 Jul 2003 07:54
    MuehBln
    

    Am Besten 2 Funktionen schreiben und die in eine separate Datei packen (z.B. SetLastPosting(forum)undGetLastPosting(forum) und GetLastPosting(forum). Das kann man dann ja schnell wieder rein/rausbauen.

    btw: C/C++ Code und Code haben die selbe Tastenkombination (Alt+c)



  • Dimah schrieb:

    Shade Of Mine schrieb:

    der phpbb code scheint mir ein graus zu sein...

    ich wuerde es brutal machen:

    eine neue tabelle erstellen die exakt soviele eintraege hat wie wir foren.
    bei jedem neuen posting wird brutal ein update ausgefuehrt unnd setzt in dieser tabelle den titel des letzten postings.
    da kannst du uhrzeit und user id auch dazu geben, dann bist du extrem schnell, da du mit einem query alles bekommst.

    allerdings musst du dann die struktur aendern, was sich aber IMHO auszahlt. denn ich wuesste nicht wie man es anders effektiv schaffen koennte.

    ungern, denn das bedeutet viele eingriffe in den orginal code, was sich negativ beim updaten auswirkt

    update wird ja wohl nicht mehr nötig sein 👎


  • Mod

    Dimah schrieb:

    ungern, denn das bedeutet viele eingriffe in den orginal code, was sich negativ beim updaten auswirkt

    ja, das ist leider der nachteil 😞

    aber ich habe mich gestern 1 stunde mit dieser datenbank sttruktur gespielt -> ich habs nicht hinbekommen mit dieser struktur den letzten beitrag effizient auszulesen.

    du kannst ja auch mal auf phpbb.com nachfragen wie man das effizient machen kann.

    wie gesagt, dass ist der einzige weg der mir eingefallen ist -> hoffentlich findet noch jemand einen besseren!



  • Vielleicht solltet ihr es doch mal mit nem Index auf die größeren Tabellen machen. Die Spalten die in dem SQL vorkommen halt in Kombination



  • Warum nicht einfach für jedes Forum eine schöne Tabelle - das ist ja kein Problem?! Und da lässt man dann brav einen Index mitlaufen (Unique oder so) und ruft einfach Element #1 für jede Tabelle auf?

    Außerdem erleichtert das das Suchen in einzelnen Foren!

    MfG SideWinder



  • kann man performancekritische Sachen nicht in C++ schreiben?



  • 🙂

    Die SQL-Abfrage ist zeitkritisch, und mySQL ist doch in C++ geschrieben.

    Ein Join über soviele Tabellen dauert... egal ob VB, C++ oder PHP.


  • Mod

    Marc++us schrieb:

    🙂
    Ein Join über soviele Tabellen dauert...

    eben 😞
    deshalb sehe ich keine andere moeglichkeit als die tabellenstruktur zu aendern 😞



  • ich habe es jetzt so gelöst

    default:
    			$sql = "SELECT f.*, p.post_time, p.post_username, u.username, u.user_id
    				FROM (( " . FORUMS_TABLE . " f
    				LEFT JOIN " . POSTS_TABLE . " p ON p.post_id = f.forum_last_post_id )
    				LEFT JOIN " . USERS_TABLE . " u ON u.user_id = p.poster_id )
    				ORDER BY f.cat_id, f.forum_order";
    			break;
    	}
    	if ( !($result = $db->sql_query($sql)) )
    	{
    		message_die(GENERAL_ERROR, 'Could not query forums information', '', __LINE__, __FILE__, $sql);
    	}
    
    	$forum_data = array();
    	while( $row = $db->sql_fetchrow($result) )
    	{
    		$forum_data[] = $row;
    	}
    
    	if ( !($total_forums = count($forum_data)) )
    	{
    		message_die(GENERAL_MESSAGE, $lang['No_forums']);
    	}
    
    //Dimah
    
    function gecachter_last_topic_on_index()
    {
        static  $topic_data = array();
        global  $forum_data, $total_forums, $db;
    
        $orig_word = array();
        $replacement_word = array();
        obtain_word_list($orig_word, $replacement_word);
    
        for($i = 0; $i < $total_forums; $i++)
        {
            if ( $forum_data[$i]['cat_id'] == 7)
            {
                $topic_data[$i]['topic_title_full'] = "&nbsp;Archiv - hier kann nur gelesen werden";
                $topic_data[$i]['topic_title_short'] = "&nbsp;Archiv - hier kann nur gelesen werden";
            }
            else if($topic_data[$i]['id'] != $forum_data[$i]['forum_last_post_id'])
            {
                $sql = "SELECT p.topic_id FROM ".POSTS_TABLE." p WHERE p.post_id = ".$forum_data[$i]['forum_last_post_id'];
                if ( !($result = $db->sql_query($sql)) )
                {
                    message_die(GENERAL_ERROR, 'Could not query forums information', '', __LINE__, __FILE__, $sql);
                }
                $row = $db->sql_fetchrow($result);
    
                $sql = "SELECT t.topic_title FROM ".TOPICS_TABLE ." t WHERE t.topic_id = ".$row['topic_id'];
                if ( !($result = $db->sql_query($sql)) )
                {
                    message_die(GENERAL_ERROR, 'Could not query forums information', '', __LINE__, __FILE__, $sql);
                }
                $row = $db->sql_fetchrow($result);
    
                if (count($orig_word))
                    $row['topic_title'] = preg_replace($orig_word, $replacement_word, $row['topic_title']);
    
                $topic_data[$i]['topic_title_full']  = $row['topic_title'];
                $topic_data[$i]['id']                = $forum_data[$i]['forum_last_post_id'];
    
                if (strlen($row['topic_title']) > 43) 
                {
                    $topic_data[$i]['topic_title_short'] = substr($row['topic_title'],0,40) . '...';
                }
                else
                {
                    $topic_data[$i]['topic_title_short'] = $row['topic_title'];
                }
    
            }
    
            $forum_data[$i]['topic_title_full'] = $topic_data[$i]['topic_title_full'];
            $forum_data[$i]['topic_title_short'] = $topic_data[$i]['topic_title_short'];
        }
    }
            gecachter_last_topic_on_index();
    
    /*	
    	//
    	// Filter topic_title not allowed to read
    	// 
    
    	if ( !($userdata['user_level'] == ADMIN && $userdata['session_logged_in']) ) {
    		$auth_read_all = array();
    		$auth_read_all = auth(AUTH_READ, AUTH_LIST_ALL, $userdata, $forum_data);
    		$auth_data = '';
    		for($i=0; $i<count($forum_data); $i++)
    		{
    			if (!$auth_read_all[$forum_data[$i]['forum_id']]['auth_read']) 
    			{
    				$forum_data[$i]['topic_title']='';
    			}
    		}
    	}
    */
    //end of Dimah
    

    und etwas weiter unten

    //Dimah
    //Orginal
    /*
    
    							if ( $forum_data[$j]['forum_last_post_id'] )
    							{
    								$last_post_time = create_date($board_config['default_dateformat'], $forum_data[$j]['post_time'], $board_config['board_timezone']);
    
    								$last_post = $last_post_time . '<br />';
    
    								$last_post .= ( $forum_data[$j]['user_id'] == ANONYMOUS ) ? ( ($forum_data[$j]['post_username'] != '' ) ? $forum_data[$j]['post_username'] . ' ' : $lang['Guest'] . ' ' ) : '<a href="' . append_sid("profile.$phpEx?mode=viewprofile&amp;" . POST_USERS_URL . '='  . $forum_data[$j]['user_id']) . '">' . $forum_data[$j]['username'] . '</a> ';
    
    								$last_post .= '<a href="' . append_sid("viewtopic.$phpEx?"  . POST_POST_URL . '=' . $forum_data[$j]['forum_last_post_id']) . '#' . $forum_data[$j]['forum_last_post_id'] . '"><img src="' . $images['icon_latest_reply'] . '" border="0" alt="' . $lang['View_latest_post'] . '" title="' . $lang['View_latest_post'] . '" /></a>';
    							}
    							else
    							{
    								$last_post = $lang['No_Posts'];
    							}
    */
    //end of Orginal
    
                                         if ($forum_data[$j]['forum_last_post_id'] )
                                         {
                                            $last_post_time = create_date($board_config['default_dateformat'], $forum_data[$j]['post_time'], $board_config['board_timezone']);
    
                                            $last_post = '&nbsp;'.$last_post_time.'<br />&nbsp;<a href="' . append_sid("viewtopic.$phpEx?"  . POST_POST_URL . '=' . $forum_data[$j]['forum_last_post_id']) . '#' . $forum_data[$j]['forum_last_post_id'] . '" title="' . $forum_data[$j]['topic_title_full'] . '">' . $forum_data[$j]['topic_title_short'] . '</a> &nbsp;(';
                                            $last_post .= ( $forum_data[$j]['user_id'] == ANONYMOUS ) ? ( ($forum_data[$j]['post_username'] != '' ) ? $forum_data[$j]['post_username'] . ' ' : $lang['Guest'] . ' ' ) : '<a href="' . append_sid("profile.$phpEx?mode=viewprofile&amp;" . POST_USERS_URL . '='  . $forum_data[$j]['user_id']) . '">' . $forum_data[$j]['username'] . '</a>';
                                            $last_post .= ')&nbsp;&nbsp;';
                                         }
                                         else
                                         {
                                            $last_post = $lang['No_Posts'];
                                         }
    
    //end of Dimah
    

    was kann ich noch optimieren?


Anmelden zum Antworten