zblog后台发文章超级慢的问题排查

zblog10个月前zblog问题解答32
zblog后台发文章超级慢的问题排查:
zb_system/cmd.php 

	case 'ArticlePst':
	...
	$zbp->BuildModule(); #慢 对应 zb_system/function/lib/zblogphp.php ZBlogPHP 的 BuildModule()

	#die('ArticlePst');

zb_system/function/lib/zblogphp.php  
	/**
	* 生成所有进Ready List的模块的Content内容并保存.
	*/
	public function BuildModule()
	{

	foreach ($GLOBALS['hooks']['Filter_Plugin_Zbp_BuildModule'] as $fpname => &$fpsignal) {
	    $fpname();
	}


	ModuleBuilder::Build(); # 慢  对应 zb_system/function/lib/modulebuilder.php ModuleBuilder 的 Build()
	#die("BuildModule");
	}

zb_system/function/lib/modulebuilder.php  
	public static function Build()
	...
	$num = 0;
	foreach (self::$Ready as $m) {
	    if (isset($zbp->modulesbyfilename[$m])) {
		$num = $num + 1;
		if ($num == 6) {
		    print($m . "\n"); # 'archives' 时慢 下面 Build 慢	    
		    #$zbp->modulesbyfilename[$m]->Build(); # 慢慢慢  对应 zb_system/function/lib/base/module.php Base__Module 的 Build()
		    die('ModuleBuilder::Build()');
		}
		$zbp->modulesbyfilename[$m]->Build();
		$zbp->modulesbyfilename[$m]->Save();
	    }
	}

zb_system/function/lib/base/module.php
    public function Build()
    {

        if ($this->NoRefresh == true) {
            return;
        }

        /*

        $this->FileName 值为 previous (翻译:最近发表)

         ModuleBuilder::$List[$this->FileName] 即 ModuleBuilder::$List['previous'] 值为:
         Array
        (
            [filename] => previous
            [function] => ModuleBuilder::LatestArticles
            [parameters] => Array
                (
                )

        )
         */


        if (isset(ModuleBuilder::$List[$this->FileName])) {

            /*
            if ($this->FileName == 'archives') {
                echo 'Build()';
                #print_r(ModuleBuilder::$List[$this->FileName]['function']); # 输出: ModuleBuilder::Archives
                #print_r(ModuleBuilder::$List[$this->FileName]['parameters']); # 输出: Array ()
                die();
            }
            */
            if (isset(ModuleBuilder::$List[$this->FileName]['function'])) {
                $f = ModuleBuilder::$List[$this->FileName]['function'];
                $p = ModuleBuilder::$List[$this->FileName]['parameters'];
                $p = is_array($p) ? $p : array();

                if ($this->FileName == 'archives') {
                    echo 'Build()';
                    print_r($f); # 输出: ModuleBuilder::Archives
                    print_r(ParseFilterPlugin($f)); # 输出: Array( [0] => ModuleBuilder [1] => Archives )
                    echo "<br>\n" . gettype($f); # 输出: string
                    echo "<br>\n" . gettype(ParseFilterPlugin($f)); # 输出:array
                    die();
                }
                # call_user_func_array 第一个参数函数名 第二个参数函数参数数组
                # 如果调用类方法: 第一个参数 是数组,第一个值是类名,第二个值是方法名,[$object, 'methodName']
                # 执行 ModuleBuilder::Archives() 慢
                
                $this->Content = call_user_func_array(ParseFilterPlugin($f), $p); # 这句慢
		#====>ModuleBuilder::Archives();# 最终 这句慢 zb_system/function/lib/modulebuilder.php 的 Archives()


                return true;
            }
        }
        return false;
    }

    #function ParseFilterPlugin($fpname) 在 zb_system/function/c_system_plugin.php 

zb_system/function/lib/modulebuilder.php 
    public static function Archives()
    {

        global $zbp;
        $template = $zbp->template;
        #print_r($template); #Template Object ...

        $tags = array();
        $urls = array(); //array(url,name,count);

        $maxli = $zbp->modulesbyfilename['archives']->MaxLi;# 0
        #print_r($zbp->modulesbyfilename['archives']->MaxLi);

        if ($maxli < 0) {
            return '';
        }

        $sql = $zbp->db->sql->Select($zbp->table['Post'], array('log_PostTime'), null, array('log_PostTime' => 'DESC'), array(1), null);
        # SELECT  log_PostTime  FROM  zbp_post  ORDER BY log_PostTime DESC LIMIT 1
	# 就这一句慢啊啊   解决办法 OPTIMIZE TABLE zbp_post; 
        print_r($sql);
        die('error');


SELECT  log_PostTime  FROM  zbp_post  ORDER BY log_PostTime DESC LIMIT 1 数据库只有几条数据 但是仍然要十几秒
原因是 在MySQL中,当表经历了大量数据的插入和删除操作后,可能会导致表的碎片化和索引的不连续,从而影响查询性能。
使用 OPTIMIZE TABLE 命令来重建表和索引,这有助于消除碎片。
这个命令会重新组织表的物理存储结构,并重建所有索引,从而可能显著提高查询性能。



对于正常使用数据库(增删改查操作),OPTIMIZE TABLE 可能会产生以下影响:

锁定表:在执行 OPTIMIZE TABLE 时,表可能会被锁定,这意味着其他用户将无法对表进行写入操作(INSERT、UPDATE、DELETE)。读取操作(SELECT)可能会受到影响,具体取决于锁的类型和持续时间。然而,对于InnoDB表,锁定通常是短暂的,并且MySQL会尽量减小锁定对并发操作的影响。
系统资源消耗:OPTIMIZE TABLE 是一个重量级操作,可能会消耗大量的系统资源(如CPU、内存和I/O)。因此,在生产环境中执行此操作时,应谨慎考虑其对系统性能的影响,并尽量在业务低峰期进行。
二进制日志(binlog):该操作会产生大量的二进制日志,如果你的主从复制环境中主库的binlog传输到从库较慢,可能会导致从库延迟增加。
综上所述,OPTIMIZE TABLE 不会删除数据,但可能会影响数据库的并发操作和系统性能。因此,在执行此操作之前,建议评估其对业务的影响,并在合适的时间窗口内进行。同时,考虑使用数据库的自动优化功能(如InnoDB的自动碎片整理)来减少手动执行 OPTIMIZE TABLE 的频率。

定期运行数据库维护任务,如 OPTIMIZE TABLE 和 ANALYZE TABLE,以保持表和索引的性能。
ANALYZE TABLE 命令会更新表的统计信息,帮助优化器做出更好的决策。 
如  ANALYZE TABLE zbp_post;


相关文章

php 函数 array_unique 是干啥的 数组去重

`array_unique` 是 PHP 中的一个函数,用于从数组中移除重复的值。它返回一个新数组,其中包含原始数组中的唯一值,并保留原始键名。以下是 `array_unique` 函数的语法:```...

zblog查询数量sql num

$where = array('=', 'log_ID', 111); $num = $zbp-&...

linux修改密码 ssh端口查看

查看ssh端口 cat /etc/ssh/sshd_config | grep Port 修改密码 passwd...

brotli 命令行工具 在centos 和 Ubuntu 分别怎么安装

在CentOS和Ubuntu上安装brotli命令行工具,可以按照以下步骤进行:在CentOS上安装brotli更新系统(可选但推荐):首先,确保你的CentOS系统已经更新到最新状态。bash复制代...