【问题标题】:Yii SQL Profiling of AJAX callsYii SQL Profiling of AJAX 调用
【发布时间】:2012-10-31 04:38:57
【问题描述】:

Yii 提供了一个设置,可以用每个 SQL 调用的执行时间来分析所有的 SQL 调用(CProfileLogRoute)。除非它不适用于 ajax 调用。如何访问这些数据?

我正在尝试查找打开登录弹出窗口的 ajax 调用的瓶颈...

类似地,CProfileLogRoute 中显示的执行时间是否包括到 SQL 服务器的网络行程(如果有)?我的数据库由 Amazon 的 RDS 托管,我想知道这是否是瓶颈所在(在本地似乎很好)。

【问题讨论】:

    标签: php database amazon-web-services yii profiling


    【解决方案1】:

    CProfileLogRoute 类有一个名为 ignoreAjaxInFireBug 的属性,默认为“true”,将其设置为 false 您可以获取有关 ajax 请求的分析信息。 p>

    http://www.yiiframework.com/doc/api/1.1/CWebLogRoute#ignoreAjaxInFireBug-detail

    'log'=>array(
        'class'=>'CLogRouter',
        'routes'=>array(
                        array(
                            'class'=>'CProfileLogRoute',
                            'ignoreAjaxInFireBug'=>false,
                            'levels'=>'error, warning, trace, info, profile',
                        ),
            ),
    

    我不认为你需要使用 firebug 来完成这项工作(这有点用词不当)。但是,如果您这样做,只需下载 firefox 并安装 firebug,您的问题仍然可以解决。

    【讨论】:

      【解决方案2】:

      您可以尝试以下面建议的方式扩展CFileLogRoute,并在应用程序的配置中启用它,如下所示:

      'log'=>array(
          'class'=>'CLogRouter',
          'routes'=>array(
              array(
                  'class'=>'ProfileLogRoute',
                  'levels' => "profile"
              )
          )
      )
      

      在这种情况下,所有已分析的查询都将写入位于protected/runtime 目录中的日志文件(覆盖processLogs 方法同样实现CProfileWebRoute 的摘要报告...不幸的是CProfileWebRoute 源自@987654323 @):

      <?php  
      class ProfileLogRoute extends CFileLogRoute
      {
          protected function processLogs($logs)
          {
              $logFile=$this->getLogPath().DIRECTORY_SEPARATOR.$this->getLogFile();
              if(@filesize($logFile)>$this->getMaxFileSize()*1024)
                  $this->rotateFiles();
              $fp=@fopen($logFile,'a');
              @flock($fp,LOCK_EX);
      
              $profileStack = array();
              $profileResults = array();
              foreach ($logs as $log)
              {
                  if ($log[1] === CLogger::LEVEL_PROFILE)
                  {
                      $message = $log[0];
                      if (!strncasecmp($message, 'begin:', 6))
                      {
                          $log[0] = substr($message,6);
                          $profileStack[] = $log;
                      }
                      else if(!strncasecmp($message, 'end:', 4))
                      {
                          $token = substr($message,4);
                          if(($last = array_pop($profileStack)) !== null && $last[0] === $token)
                          {
                              $info = array(
                                  'delta' => $log[3] - $last[3],
                                  'category' => $last[2],
                                  'time' => $last[3]
                              );
                              $this->aggregateResult($token, $info, $profileResults);
                          }
                          else
                          {
                              throw new CException(Yii::t('yii','CProfileLogRoute found a mismatching code block "{token}". Make sure the calls to Yii::beginProfile() and Yii::endProfile() be properly nested.',
                                  array('{token}'=>$token)));
                          }
                      }
                  }
                  else
                  {
                      @fwrite($fp,$this->formatLogMessage($log[0],$log[1],$log[2],$log[3]));
                  }
              }
      
              if (!empty($profileResults))
              {
                  $now = microtime(true);
                  while(($last = array_pop($profileStack)) !== null)
                  {
                      $info = array(
                          'delta' => $now - $last[3],
                          'category' => $last[2],
                          'time' => $last[3]
                      );
                      $token = $last[0];
                      $this->aggregateResult($token, $info, $profileResults);
                  }
      
                  $entries = array_values($profileResults);
                  $func = create_function('$a,$b','return $a["total"]<$b["total"]?1:0;');
                  usort($entries, $func);
                  foreach ($entries as $entry)
                  {
                      $message = sprintf("Min: % 11.8f    Max: % 11.8f    Total: % 11.8f    Calls: % 3d    %s", $entry['min'], $entry['max'], $entry['total'], $entry['calls'], $entry['token']);
                      @fwrite($fp, $this->formatLogMessage($message, CLogger::LEVEL_PROFILE, $entry['category'], $entry['time']));
                  }
              }
      
              @flock($fp,LOCK_UN);
              @fclose($fp);
          }
      
          protected function aggregateResult($token, $info, &$results)
          {
              if (isset($results[$token]))
              {
                  if ($info['delta'] < $results[$token]['min'])
                      $results[$token]['min'] = $info['delta'];
                  else if($info['delta'] > $results[$token]['max'])
                      $results[$token]['max'] = $info['delta'];
                  $results[$token]['calls']++;
                  $results[$token]['total'] += $info['delta'];
                  return;
              }
      
              $results[$token] = array(
                  'token' => $token,
                  'calls' => 1,
                  'min' => $info['delta'],
                  'max' => $info['delta'],
                  'total' => $info['delta'],
                  'category' => $info['category'],
                  'time' => $info['time']
              );
          }
      }
      

      如果你想知道 Yii 是如何衡量 SQL 执行时间的,你可以查看 CDbCommand 类的源代码 - queryInternal 方法,更准确地说。分析介于 Yii::beginProfile('system.db.CDbCommand.query...')Yii::endProfile('system.db.CDbCommand.query...') 调用之间。如您所见,这两个调用都在同一个方法中,因此分析时间不包括网络传输。可能问题在于您的远程数据库服务器在巨大的负载下运行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-15
        • 2013-08-31
        相关资源
        最近更新 更多