Typecho 获取随机文章性能最优版

一般的来说,开发者获取随机文章最简单的方式就是使用 order by RAND(),然而这种方式在数据量稍大的时候可能产生数百毫秒的延迟。关于 mysql RAND() 的性能分析,网上已经很有多的文章了,本文不再赘述。大概意思就是,在ORDER BY从句里面不建议使用RAND()函数,因为这样会导致数据列被多次扫描。

以下直接给出优化后的获取随机文章的代码,能够极大的减少数据库查询时间。

typecho 版本:

$db = Typecho_Db::get();
$prefix = $db->getPrefix();

$adapterName = $db->getAdapterName();//兼容非MySQL数据库
if ($adapterName == 'pgsql' || $adapterName == 'Pdo_Pgsql' || $adapterName == 'Pdo_SQLite' || $adapterName == 'SQLite') {
    $order_by = 'RANDOM()';
    $user_former = false;
} else {
    $order_by = 'RAND()';
    $user_former = true;

}
// 使用原生sql
if($user_former){
    $sql = "SELECT * FROM `{$prefix}contents` WHERE cid >= (SELECT floor( RAND() * ((SELECT MAX(cid) FROM `{$prefix}contents`)-(SELECT MIN(cid) FROM `{$prefix}contents`)) + (SELECT MIN(cid) FROM `{$prefix}contents`))) and type='post'
            and status='publish' and (password is NULL or password='') ORDER BY cid LIMIT {$random};";
    $result = $db->query($sql);
}else{
    $sql = $db->select()->from('table.contents')
        ->where('status = ?', 'publish')
        ->where('table.contents.created <= ?', time())
        ->where('type = ?', 'post')
        ->limit($random)
        ->order($order_by);
    $result = $db->fetchAll($sql);
}

实现原理

假设数据库的主键为 cid。 比如最小的文章cid是1,最大的文章cid是10,那就从1到10之间选一个随机数,比如5,然后假设我们要取一篇文章,那么就是从 1 + 5 到 10 之间取。一定程度上降低了数据量。

但是怎么看都是薛定谔的处理方法,但总归比原来性能好了。
::(超赞)

给TA打赏
共{{data.count}}人
人已打赏
建站教程软件工具

首发 typecho 时光机单页 typecho-whisper

2021-3-3 23:10:00

建站教程技术活

typehco 插件加上github版本检测

2021-3-8 12:40:00

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索