2011-12-12 81 views
2

我想实现缓慢的查询日志到我的数据库类,但我得到奇怪的结果。它目前主要记录所有查询,并且它说大多数查询需要大约0.8秒的时间才能运行,而且我不明白,因为这是在我的开发人员机器上,而且这个开发人员机器的负载不是很重。如何记录查询执行时间?

地狱,我甚至试图运行在phpMyAdmin查询,他们在那里非常快。

我把它放在错误的地方吗?或者我错过了什么?

class database { 
    protected $_mysqli; 
    protected $_debug; 

    public function __construct($host, $username, $password, $database, $debug) { 
     $this->_mysqli = new mysqli($host, $username, $password, $database); 
     $this->_debug = (bool) $debug; 
     if (mysqli_connect_errno()) { 
      if ($this->_debug) { 
       echo mysqli_connect_error(); 
       debug_print_backtrace(); 
      } 
      return false; 
     } 
     return true; 
    } 

    public function q($query) { 
     $incomingq = $query; 
     if ($query = $this->_mysqli->prepare($query)) { 
      if (func_num_args() > 1) { 
       $x = func_get_args(); 
       $args = array_merge(array(func_get_arg(1)), 
        array_slice($x, 2)); 
       $args_ref = array(); 
       foreach($args as $k => &$arg) { 
        $args_ref[$k] = &$arg; 
       } 
       call_user_func_array(array($query, 'bind_param'), $args_ref); 
      } 
      // Settings 
      $SLOW_LOG_TIME = 0.8; // (sec) 
      $SLOW_LOG_FILE = 'php_slow.txt'; 
      $SLOW_LOG_START = time(); // (sec) 

      $query->execute(); 

      // Logging 
      $SLOW_LOG_END = microtime(TRUE); 
      $time = $SLOW_LOG_END - $SLOW_LOG_START; 
      if ($time > $SLOW_LOG_TIME) 
      { 
       $log = date('Y-m-d H:i:s') . "\t" . round($time, 3) . "\t" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] . "\t" . str_replace(array("\t" , "\n"), "", $incomingq) . "\r\n"; 
       $fp = fopen($SLOW_LOG_FILE, 'a+'); 
       fwrite($fp, $log); 
       fclose($fp); 
      } 

      if ($query->errno) { 
       if ($this->_debug) { 
        echo mysqli_error($this->_mysqli); 
        debug_print_backtrace(); 
       } 
       return false; 
      } 

      if ($query->affected_rows > -1) { 
      // if ($query->sqlstate == "00000") { 
       return $query->affected_rows; 
      } 
      $params = array(); 
      $meta = $query->result_metadata(); 
      while ($field = $meta->fetch_field()) { 
       $params[] = &$row[$field->name]; 
      } 
      call_user_func_array(array($query, 'bind_result'), $params); 

      $result = array(); 
      while ($query->fetch()) { 
       $r = array(); 
       foreach ($row as $key => $val) { 
        $r[$key] = $val; 
       } 
       $result[] = $r; 
      } 
      $query->close(); 
      return $result; 
     } 
     else { 
      if ($this->_debug) { 
       echo $this->_mysqli->error; 
       debug_print_backtrace(); 
      } 
      return false; 
     } 
    } 

    public function handle() { 
     return $this->_mysqli; 
    } 

    public function last_insert_id() 
    { 
     return $this->_mysqli->insert_id; 
    } 
} 

回答

5

您已经使用错误的计量单位为这样的:$SLOW_LOG_START = time();, 时间()是排在第二。

它应该与$SLOW_LOG_END = microtime(TRUE);一致。

虽然microtime(TRUE)以微秒为单位。

所以,改变$SLOW_LOG_START = microtime(TRUE);

+0

非常感谢!有时简单的错误是最糟糕的:) – John

3

你所得到的开始时间精确到秒和结束时间到微秒。

使用microtime代替$SLOW_LOG_START,否则您的测量结果可能仅仅是一整秒钟的时间而已。

这应该解决您的问题。

2

我确定你已经知道它了,但是MySQL有自己的slow query logger来记录超过指定时间的任何查询。这样,你需要自己构建它。

+0

谢谢高拉夫,我会在稍后的阶段看看这个:) – John