Howto: Fixing slow comments

So you got a nifty new blog. You turned on all the neat features… of course you wanted individual, daily, weekly, monthly, and category archives! Hell yea, you needed a sidebar on every page, plus yearly calendar pages sure would come in handy. Eventually the blog gets popular and you have to add filtering for all that spam, and people want to get emails for new comments, so you add comment subscription software. Still, everything ran really fast.

Then you post almost daily, to a dozen different categories, for over a year. Now you’ve got thirteen hundred posts and over three thousand comments and it starts to take two, three, even five minutes to post a new comment. Why? Because you’re running every comment through your blacklist (barely any slowdown, only a second or two), your email subscription software (perhaps a bit more time added, depending on your implementation), and then you’re rebuilding up to seven (or more, if you assigned the entry to multiple categories) web pages, some of which contain hundreds of seperate entries, every time someone hits the post comment button. That last thing is what’s really killing the response time.

You take some minor steps. You eliminate some MTIncludes, take all the dollar signs out of your MT tags (just copy and paste into a text editor then search a replace all <$ with < and all $> with >), you turn off your email notifier and your spam filter. Maybe you even turn off an archive type or two. It’s still ridiculously slow.

Now it’s time to get serious.

I noticed that the only reason MovableType rebuilds most archives and indexes is to update the little number in the comments link, but to do that it still has to load possibly hundreds of entries out of the database and write them to disk. So I wrote the following code that updates that number straight from the database via PHP (this requires you’re using MySQL as your database):

<?php
$host = 'localhost';  // database server hostname
$user = 'root';  // database username
$password = 'password';  //  database password
$database = 'database';  // MT database
mysql_connect( $host, $user, $password );
mysql_select_db( $database );

// get the no. of times this entry has been read and the number of comments
$rs = mysql_query( 'SELECT COUNT(*) FROM mt_comment WHERE comment_entry_id = <MTEntryID>');
$comments = mysql_result( $rs, 0 )
?>

Of course, replace your username, password, and database in the variables at the top. Then find the MT tag, <$MTEntryCommentCount$>, that usually prints the comment number and replace the whole tag with this code: <? echo $comments; ?>. Now MovableType doesn’t have to rebuild that index or archive file on comment submission.

Check your speed now. I think MT checks for comment tags in a template before rebuilding a file, so just removing the tags might make you happy without doing the next step. A lot of people are squeamish about hacking the actual MT installation code, but I’m not scared! Plus, my rebuilds were still really slow, perhaps because just checking the templates for tags takes a bit of time.

Now’s a good time to backup your blog. I just backup the whole database, but perhaps exporting all entries and comments to text would be a good idea, too. Then pull up $MTDIR$/lib/MT/App/Comments.pm* (back it up first, too!) in a text editor. Find the line that contains rebuild_indexes, it’s on 107 in 2.64. Before this line insert:

if ($entry->blog_id != 1) {

Replace the 1 with whatever the ID for your particular blog is. Then put a closing bracket after line 113 and add this else statement:

else {
$app->_rebuild_entry_archive_type( Entry => $entry, Blog => $blog, ArchiveType => 'Individual' )
or return $app->error($app->translate(
"Rebuild failed: [_1]", $app->errstr));
}

Once your done the code should look like this:

if ( $comment->blog_id $gt; 1 ) {
$app->rebuild_indexes( Blog => $blog )
or return $app->error($app->translate(
"Rebuild failed: [_1]", $app->errstr));
$app->rebuild_entry( Entry => $entry )
or return $app->error($app->translate(
"Rebuild failed: [_1]", $app->errstr));
}
else {
$app->_rebuild_entry_archive_type( Entry => $entry, Blog => $blog, ArchiveType => 'Individual' )
or return $app->error($app->translate(
"Rebuild failed: [_1]", $app->errstr));
}

Now the only entry that’s rebuilt when someone submits a comment is the individual post, the one that lists comments in full at the bottom. Everything should be much faster.

*If you’re using Blacklist just follow the same directions on $MTDIR$/extlib/jayallen/Blacklist.pm. The code should go in around the first mention of rebuild_indexes, on around line 3065 in 1.61b.
This assumes you want all but one of the blogs on your system to rebuild normally. If you only have one blog, just leave the code as is. If you want to rebuild multiple blogs the fast way you’ll have to add some “or” statements in the parens. Write to me if you have any trouble.

Popularity: 4% [?]

2 Comments on “Howto: Fixing slow comments”

  1. I’ve been hesitant to modify the MT source code, only because upgrading will then be a big pain in the ass. However, who knows when the next release of MT will be? And maybe the next release will include all these changes any way, so it shouldn’t matter. I’ve got to sit down and hammer out a bunch of changes to my install, simply because I want to make comments viewable dynamically, as well as extended entries. I’ve gotta teach myself PHP at some point too. :)

     
  2. Yea, it’s a pain in the ass to upgrade with hacks. Most of the hacks I’ve done recently have been on Blacklist.pm, and that gets updated fairly often. I keep meaning to write all my hacks to .patch files, then I could just reapply the patches on upgrade with minimal hassle.

     

Leave a Reply