本文转自:http://www.solagirl.net/wp-commentmeta-slowing-down-your-blog.html

今天deluxeblogtips发布一篇文章题目是Don’t Use Akismet让我很是好奇,我一直觉得Akismet是官方插件,为什么不要用呢?文章描述道博客速度变的很慢,检查原因时发现Akismet在wp_commentmeta表中产生了非产多的log记录,导致该表达到127M的巨型尺寸,对一个只有200篇文章不到的小博客来说非常离谱。我很好奇的检查了一下自己的wp_commentmeta表,结果让我吃惊!

wp_commentmeta正在变成垃圾回收站

我的垃圾评论不多,但wp_commentmeta表竟然有2848条记录,分析了一下这些记录都是什么,结果让我吐血!

Akismet在记录的comment meta字段如下

1
2
3
4
5
6
akismet_as_submitted
akismet_history
akismet_result
akismet_user
akismet_user_result
akismet_rechecking

想知道Akismet产生了多少数据么,运行下面的SQL语句就知道了

1
2
3
SELECT COUNT( * )
FROM `wp_commentmeta`
WHERE `meta_key` LIKE '%akismet%'

结果是2598!没错,我的数据表中Akismet的log记录占到了91.2%。

具体占比如下

1
2
3
4
5
6
akismet_as_submitted  81条
akismet_history       1412条
akismet_result        1019条
akismet_user          43条
akismet_user_result   43条
akismet_rechecking    0

其中akismet_as_submitted的每一条数据都非常大,虽然条数不多,但很占地方。

于是我很好奇其它的数据是什么,会不会还有点用?看了一下,又要吐了,是多说的log数据,我用多说不过短短两周时间,竟然也产生了250条日志数据。

1
2
3
4
SELECT count( * )
FROM `wp_commentmeta`
WHERE meta_key = 'duoshuo_post_id' or meta_key = 'duoshuo_parent_id'
结果:250

如果你好奇我的wp_commentmeta表都干了些什么,不妨做个简单的加法

1
2598 + 250 = 2848

这恰好是我wp_commentmeta表的数据总数,也就是说这个表完全被无用的日志数据占据,而且有越来越大的趋势。我的博客访问量不大,垃圾评论不多,所以没构成威胁。如果是垃圾评论超级多的blog,那就要命了。

Akismet设计缺陷?

这是Akismet的设计缺陷吗?看了一下Akismet的代码,它使用wp cron定期删除akismet_as_submitted这个比较占地方的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
add_action('akismet_scheduled_delete', 'akismet_delete_old_metadata');
function akismet_delete_old_metadata() {
    global $wpdb;
    $now_gmt = current_time( 'mysql', 1 );
    $interval = apply_filters( 'akismet_delete_commentmeta_interval', 15 );
    # enfore a minimum of 1 day
    $interval = absint( $interval );
    if ( $interval < 1 ) {
        return;
    }
    // akismet_as_submitted meta values are large, so expire them
    // after $interval days regardless of the comment status
    while ( TRUE ) {
        $comment_ids = $wpdb->get_col( "SELECT $wpdb->comments.comment_id FROM $wpdb->commentmeta INNER JOIN $wpdb->comments USING(comment_id) WHERE meta_key = 'akismet_as_submitted' AND DATE_SUB('$now_gmt', INTERVAL {$interval} DAY) > comment_date_gmt LIMIT 10000" );
        if ( empty( $comment_ids ) ) {
            return;
        }
        foreach ( $comment_ids as $comment_id ) {
            delete_comment_meta( $comment_id, 'akismet_as_submitted' );
        }
    }
}

Akismet会每隔15天删除一次数据,如果你的wp cron确实是工作的,那么没关系,至少wp_commentmeta表不会爆炸。如果评论非常多,那有点麻烦,15天的间隔显得有点长,最好更改一下,在主题的functions.php中添加代码

1
2
3
4
add_filter('akismet_delete_commentmeta_interval', 'set_akismet_interval');
function set_akismet_interval( $interval ) {
    return 2;
}

设置成每隔2天清除一次。

如果你的wp cron不工作,评论又很多,那使用用akismet就是一场噩梦,建议检查一下wp_commentmeta表,不要被它拖慢了你的blog。

删除log数据

Akismet的log数据有多大用处我不知道,但多说的铁定没有,早就不用多说了。我的wp_commentmeta表全部都是没用的数据,于是直接Delete *搞定了。

如果只想删除Akismet的数据,可以在phpmyadmin中运行下面的SQL语句

1
delete from wp_commentmeta where meta_key='akismet_as_submitted' or meta_key='akismet_history' or  meta_key='akismet_rechecking' or meta_key='akismet_result' or meta_key='akismet_user' or  meta_key='akismet_user_result'

删除数据后暂时没有发现对Akismet有任何影响。