繁体   English   中英

使用键存在时PHP Mysql性能不佳

[英]PHP Mysql Poor performance when Using Key Exists

关于使用使用OO技术的PHP检索记录所花费的时间,我遇到了性能不佳的问题。

这是从MySQL返回行,实例化并确保属性存在的代码

 public function find_by_sql($sql="") {
            global $database;
            $result_set = $database->query($sql);
            //we can use this later
            $this->sql = $sql;
            $object_array = array();
            while ($row = $database->fetch_array($result_set)) {
              $object_array[] = static::instantiate($row);
            }
            return $object_array;
     }

    private static function instantiate($record) {
            // Could check that $record exists and is an array
            $class_name = get_called_class();
            $object = new $class_name;
            foreach($record as $attribute=>$value){
              if($object->has_attribute($attribute)) {
                $object->$attribute = $value;
              }
            }
            return $object;
    }
    private function has_attribute($attribute) {
          // We don't care about the value, we just want to know if the key exists
          // Will return true or false
          return array_key_exists($attribute, $this->attributes());
    }

          protected function attributes() { 
                // return an array of attribute names and their values
              $attributes = array();
              foreach(static::$db_fields  as $field) {
                if(property_exists($this, $field)) {
                  $attributes[$field] = $this->$field;
                }
              }
              return $attributes;
        }

db_fields数组已在其他地方定义,例如

protected static $db_fields = array('car_id', 'make', 'model', 'reg')

我已经跟踪了执行检查以查看密钥是否存在的功能的瓶颈。 我注释掉了下面的代码,性能提高了100%:

    private static function instantiate($record) {
            // Could check that $record exists and is an array
            $class_name = get_called_class();
             $object = new $class_name;
            foreach($record as $attribute=>$value){
               ///if($object->has_attribute($attribute)) {
                $object->$attribute = $value;
             /// }
            }
            return $object;
    }

为了让您对使用该函数对性能的影响有一个了解,调用该函数需要花费6秒的时间。

任何人都可以就不使用该功能的影响向我提出建议,如果有办法可以保留它但可以提高性能。

我知道array_key_exists()用于查看查询中返回的列是否在属性数组$ this-> attributes()中,该属性数组最初在$ db_fields中声明。

我检查了$ this-> attributes()数组,它打印了以下内容

array(3){[“” car_id“] => NULL [” make“] => NULL [” model“] => [” reg“] => NULL}

isset()是array_key_exists()的替代方法,但不能使用,因为尽管键存在,但由于值为null而为false。 由于性能缓慢,这使我回到不使用array_key_exists()函数的解决方法

多亏了迈克尔·伯可夫斯基(Michael Berkowski)的评论,我将问题范围缩小为对has_attributes方法中对attribute()方法的不断调用。 尽管可能有更完善的方法可以将其添加到has_attribute方法中

        private function has_attribute($attribute) {
            ///if this is the first call attr_array will be empty so we will populate it by calling attributes method
              if (empty($this->attr_array)) { 
                  $this->attr_array = $this->attributes();
              } 
              ///either way, at this point attr_array is populated 
              return array_key_exists($attribute, $this->attr_array);
        }

这将页面的加载时间减少了70%

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM