Seite 1 von 1
PHPBB Forum langsam
Verfasst: Mi 01 Nov, 2006 11:53
von Captain
Guten Morgen zusammen,
nachdem GRDB als solches eigentlich recht schnell läuft, ist es vor allem unser PHPBB Forum, welches mitunter recht langsam läuft. Das liegt natürlich an der deutlich gestiegenen Anzahl an Usern und auch an den immer mehr werdenden Posts. Ich werde daher in diesem Thread beschreiben, welche Codeoptimierungen ich in den einzelnen Skripten anwende, vielleicht hilft das dem einen oder anderen großen Forenbetreiber auch weiter. Ich würde mich freuen, wenn sich hierzu eine fundierte Diskussion ergibt. Mich würde interessieren, was andere Forenbetreiber in dieser Angelegenheit so alles unternehmen....
SEARCH.PHP
Die Suchfunktion schluckt nicht nur in der DB am meisten Ressorucen sondern auch bei ihrer Anwendung im Forum. Um das etwas zu verschlanken habe ich folgende Tune-Ups:
Code: Alles auswählen
$sql = "SELECT topic_id
FROM " . POSTS_TABLE . "
WHERE post_id IN (" . implode(", ", $search_id_chunks[$i]) . ")
$where_sql";
GROUP BY topic_id";
Das GROUP BY-Statement kommt 2 mal vor. Bei größeren Boards ist es ratsam, dies zu entfernen und testweise auszukommentieren.
Code: Alles auswählen
$sql = "SELECT topic_id
FROM " . POSTS_TABLE . "
WHERE post_id IN (" . implode(", ", $search_id_chunks[$i]) . ")
$where_sql";
//GROUP BY topic_id";
Verfasst: Mi 01 Nov, 2006 11:57
von Captain
SEARCH.PHP
Der folgende Code
Code: Alles auswählen
//
// Look up data
//
if ( $show_results == 'posts' )
{
$sql = "SELECT p.post_id
FROM " . FORUMS_TABLE . " f, " . TOPICS_TABLE . " t, " . USERS_TABLE . " u, " . POSTS_TABLE . " p WHERE p.post_id IN ($search_results)
AND f.forum_id = p.forum_id
AND p.topic_id = t.topic_id
AND p.poster_id = u.user_id";
}
else
{
$sql = "SELECT t.topic_id
FROM " . TOPICS_TABLE . " t, " . FORUMS_TABLE . " f, " . USERS_TABLE . " u, " . POSTS_TABLE . " p, " . POSTS_TABLE . " p2, " . USERS_TABLE . " u2
WHERE t.topic_id IN ($search_results)
AND t.topic_poster = u.user_id
AND f.forum_id = t.forum_id
AND p.post_id = t.topic_first_post_id
AND p2.post_id = t.topic_last_post_id
AND u2.user_id = p2.poster_id";
}
wird bedeutend schneller in dieser Form ausgeführt:
Code: Alles auswählen
switch ( $sort_by )
{
case 1:
case 2:
if ( $show_results == 'posts' )
{
$sql = "SELECT p.post_id FROM " . TOPICS_TABLE . " t, " . POSTS_TABLE . " p WHERE p.post_id IN ($search_results) AND p.topic_id = t.topic_id ";
}
else
{
$sql = "SELECT t.topic_id FROM " . TOPICS_TABLE . " t WHERE t.topic_id IN ($search_results) ";
}
$sql .= " ORDER BY ";
$sql .= 't.topic_title';
break;
case 3:
if ( $show_results == 'posts' )
{
$sql = "SELECT p.post_id FROM " . USERS_TABLE . " u, " . POSTS_TABLE . " p WHERE p.post_id IN ($search_results) AND p.poster_id = u.user_id";
}
else
{
$sql = "SELECT t.topic_id FROM " . TOPICS_TABLE . " t, " . USERS_TABLE . " u WHERE t.topic_id IN ($search_results) AND t.topic_poster = u.user_id ";
}
$sql .= " ORDER BY ";
$sql .= 'u.username';
break;
case 4:
if ( $show_results == 'posts' )
{
$sql = "SELECT p.post_id FROM " . POSTS_TABLE . " p WHERE p.post_id IN ($search_results) ORDER BY p.forum_id ";
}
else
{
$sql = "SELECT t.topic_id FROM " . TOPICS_TABLE . " t WHERE t.topic_id IN ($search_results) ORDER BY t.forum_id ";
}
break;
default:
if ( $show_results == 'posts' )
{
$sql = "SELECT post_id FROM " . POSTS_TABLE . " WHERE post_id IN ($search_results) ORDER BY post_id ";
}
else
{
$sql = "SELECT topic_id FROM " . TOPICS_TABLE . " WHERE topic_id IN ($search_results) ORDER BY topic_last_post_id ";
}
break;
}
Verfasst: Mi 01 Nov, 2006 12:04
von Captain
VIEWTOPIC.PHP
Bei JEDEM Zugriff auf ein Topic findet auch das Update der Views statt. Das kann bei großen Boards ein echtes Problem werden, zumal wenn wir ehrlich sind die Views eines Topics keiner sooooo genau nimmt. Ein Quick&Dirty Hack wäre folgendes:
Ersetze:
Code: Alles auswählen
$sql = "UPDATE " . TOPICS_TABLE . " SET topic_views = topic_views + 1 WHERE topic_id = $topic_id";
if ( !$db->sql_query($sql) )
{
message_die(GENERAL_ERROR, "Could not update topic views.", '', __LINE__, __FILE__, $sql);
}
durch
Code: Alles auswählen
if (mt_rand(1,3) == 1) {
$sql = "UPDATE " . TOPICS_TABLE . " SET topic_views = topic_views + 3 WHERE topic_id = $topic_id";
if ( !$db->sql_query($sql) )
{
message_die(GENERAL_ERROR, "Could not update topic views.", '', __LINE__, __FILE__, $sql);
}
}
Is klar ne? Statt jeden Zugriff zu protokollieren wird statistisch gesehen jeder dritte Zugriff verdreifacht. Damit ist man zumindest statistisch wieder da wo man ohnehin gelandet wäre, aber mit einer Reduktion der Update-Routinen um 66%. Genau ist diese Lösung natürlich nicht, aber im Mittel stimmt der Wert.
Verfasst: Mi 01 Nov, 2006 12:11
von Captain
INDEX.PHP
Auch an der Startseite kann man einiges drehen. Zum Beispiel dies:
Code: Alles auswählen
if ( $userdata['session_logged_in'] )
{
$sql = "SELECT t.forum_id, t.topic_id, p.post_time
FROM " . TOPICS_TABLE . " t, " . POSTS_TABLE . " p
WHERE p.post_id = t.topic_last_post_id
AND p.post_time > " . $userdata['user_lastvisit'] . "
AND t.topic_moved_id = 0";
if ( !($result = $db->sql_query($sql)) )
{
message_die(GENERAL_ERROR, 'Could not query new topic information', '', __LINE__, __FILE__, $sql);
}
$new_topic_data = array();
while( $topic_data = $db->sql_fetchrow($result) )
{
$new_topic_data[$topic_data['forum_id']][$topic_data['topic_id']] = $topic_data['post_time'];
}
}
Normalerweise startet die Index damit alle Foren zu durchsuchen, inwieweit neue Antworten seit dem letzten Besuch hinzugekommen sind. Schön und gut, kann aber bei großen Foren Probleme machen. Hier ein kleiner Hack:
Code: Alles auswählen
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";
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 ($row['post_time'] > $userdata['user_lastvisit']) $new_topic_data[$row['forum_id']][$row['topic_id']] = $row['post_time'];
}