[英]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.