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

zblog12个月前zblog问题解答41
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;


相关文章

宝塔升级到最新版 python升级 重新执行更新命令,重新安装面板使用的python环境,此操作不会对您的网站、数据库等造成影响,仅仅是针对面板使用的环境修复。

1、将当前Python环境做个备份的操作mv /www/server/panel/pyenv/ /www/backup/pyenv_backup2、重新执行更新命令,重新安装面板使用的python环境...

【zblog用户】获取用户作者的 select option选项

<?php echo OutputOptionItemsOfMember(0);?> 参数0是默认选中的作者id 输出 <optio...

重启!

重启!

重启mysql 和 phpservice mysqld restart service php-fpm restart或systemctl restart mysqldsystemctl r...

Nginx没有防火墙 Nginx设置加上 垃圾蜘蛛过滤

 if ($http_user_agent ~* "censys|bytedance|GPTBot|openai|Amazonbot|dotbot|c...

phpstorm中的正则表达式替换 编辑器IDE

phpstorm中的正则表达式替换 编辑器IDE

phpstorm中的正则表达式替换 编辑器IDE...

php curl 典型案例代码 curl例子 curl_init() curl_setopt

      $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url);...