powerbook_blog

klein, praktisch, unverdaulich seit 2004

WordPress: Performance-Bremse Customizable Post Listings

| Keine Kommentare

Ich nutze schon seit Ewigkeiten das Plugin Customizable Post Listings, um in der Spalte rechts die letzten Kommentare anzuzeigen. Die Funktion, die WordPress da von Haus aus mitliefert mag ich nicht. Ich will nicht die letzten 10 Kommentare sehen, sondern die letzten 10 Artikel anzeigen, die kommentiert wurden. Aus wohl diversen Gründen hat mein kleiner Server seit einem Weilchen Performance Probleme. Da hatte ich vor einer kleinen Ewigkeit mal das mysql slow query log aktiviert und habe da eben mal reingeschaut.

Eben jenes Plugin taucht da mit braver Regelmässigkeit mit seinem Query auf. Ich habe mir das mal genauer angesehen und einen kleinen Hack eingefügt, der die Performance des Querys mal eben um 1/3 reduziert und dazu noch das Query zumindest minutenweise cachen lässt.

Im Urzustand sieht das Query so aus:

SELECT wp_posts . * , MAX( comment_date ) AS max_comment_date
FROM wp_comments
LEFT JOIN wp_posts ON wp_posts.ID = wp_comments.comment_post_ID
WHERE wp_posts.post_date <= '2009-11-02 10:19:42' AND ( wp_posts.post_status = 'publish' ) AND wp_posts.post_password = '' AND wp_comments.comment_approved = '1' GROUP BY wp_posts.ID ORDER BY max_comment_date DESC LIMIT 0, 10;

Es matscht also alle Artikel und Kommentare zusammen, wobei die Artikel älter sein müssen als die aktuelle Zeit. Gerade letzteres lässt ein Cachen natürlich nicht zu, weil die Sekunden ja bekanntlich lustig vor sich hintickern. In Zeile 73 des Plugins findet sich die verantwortliche Zeile.

$now = current_time('mysql');

Ersetzt man diese Zeile nun durch ein:

$now = date("Y-M-D H:m");

so kann man zumindest minütlich das Query cachen. Im Prinzip ist der ganze Spass aber auch nur interessant, wenn man viele Postings am Tag schreibt. Wenn ich mir meine Posting-Frequenz so ansehe, selbst an den Tagen, an denen ich viel schreibe, so ist es für mich auch in Ordnung, wenn der aktuellste Beitrag für bis zu maximal 10 Minuten nicht in der Leiste rechts erscheint. Das gilt ja sowieso nur für den Fall, dass innerhalb der ersten 10 Minuten nach meinem Verfassen schon jemand kommentiert. Das ist in letzter Zeit und auch rückblickend eher nicht so der Fall. Also kommen ich prima damit aus, wenn ich die Minuten der aktuellen Zeit nach unten abrunde:

$now = date("Y-m-d H:").str_pad( floor(date("i")/10)*10 ,2,"0",STR_PAD_LEFT);

Jetzt wird das Query also schon mal gecacht. Nun ist immer noch das Problem, dass das Query die über 12.000 Kommentare den über 7.000 Beiträgen zuordnet. Das macht eigentlich so gar keinen Sinn, weil man ja eh nur die letzten Kommentare sehen möchte. Also bohre ich den originalen Quelltext in Zeile 101

if ($add_recent_comment_to_sql) $sql .= "AND $tableposts.ID = $tablecomments.comment_post_ID AND $tablecomments.comment_approved = '1' ";

auf, in dem ich nur noch die Kommentare der letzten 14 Tage durchsuchen lassen. Je nachdem, wie oft ihr Kommentare bekommt, kann man den Zeiraum natürlich auch kürzer oder länger halten:

if ($add_recent_comment_to_sql){
$date14daysago = date("Y-m-d 00:00:00",time()-(14*24*60*60));
$sql .= "AND $tablecomments.comment_date > '".$date14daysago."' AND
$tableposts.ID = $tablecomments.comment_post_ID AND
$tablecomments.comment_approved = '1' ";
}

Das neue Query sieht jetzt so aus:

SELECT wp_posts . * , MAX( comment_date ) AS max_comment_date
FROM wp_comments, wp_posts
WHERE wp_posts.post_date <= '2009-11-02 12:00'
AND (wp_posts.post_status = 'publish')
AND wp_posts.post_password = ''
AND wp_comments.comment_date > '2009-10-19 00:00:00'
AND wp_posts.ID = wp_comments.comment_post_ID
AND wp_comments.comment_approved = '1'
GROUP BY wp_posts.ID
ORDER BY max_comment_date DESC
LIMIT 0 , 10

Ich so habe ich jetzt statt pro Seitenaufruf pro Sekunde, der bislang bei dem obenstehenden originalen Query noch bis zu 1.7000 Sek benötigt hat, nur noch einen Abfragezeit von 0.1700 Sek, im gecachten Zustand sogar nur noch 0.0004 Sek. Ich freue mich.

Nachmachen auf eigene Gefahr. GMT-Zeiten werden bei dem Hack ausser Acht gelassen. Sowieso solltet ihr wissen, was ihr tut.

Schreib einen Kommentar

Pflichtfelder sind mit * markiert.