我正在使用Zend Framework 1.11并尝试加速检索客户端应用程序的模型数据。我尝试了三种方法,每种方法的速度大致相同,让我难以接受。
对于此示例,我正在检索采购订单及其物料和所有相关的地址记录。数据分布在三个表格中:purchase_orders
,purchase_order_items
和purchase_order_addresses
。
架构如您所料:
mysql> DESCRIBE purchase_orders;
+--------------------+--------------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| purchase_order_num | varchar(250) | NO | UNI | NULL | |
mysql> DESCRIBE purchase_ord_contents;
+-------------------+---------------------------------------+------+-----+--------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------------------------------------+------+-----+--------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| purchase_order_id | int(11) | NO | MUL | NULL | |
| sku | varchar(250) | NO | MUL | NULL | |
| name | varchar(250) | YES | | NULL | |
mysql> DESCRIBE purchase_order_addresses;
+-------------------+------------------------------------+------+-----+-------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------------------------+------+-----+-------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| purchase_order_id | int(11) | NO | MUL | NULL | |
| label | varchar(255) | NO | | NULL | |
| address_line_1 | varchar(255) | NO | | NULL | |
....etc.
方法1(findDependentRowset) - 约12秒内的1000条记录
foreach($this->fetchSearchResults($searchParams) as $orderRow){
$orderData = $orderRow->toArray();
// both of these methods call findDependentRowset
$orderData['items'] = $orderRow->getItems()->toArray();
$orderData['addresses'] = $orderRow->getAddresses()->toArray();
$results[] = $orderData;
}
方法2(嵌套SQL查询,1000条记录~9秒)
foreach($this->fetchSearchResults($searchParams) as $orderRow){
$orderData = $orderRow->toArray();
$orderData['items'] = self::$items->fetchAll(['purchase_order_id = ?' => $row->id])->toArray();
$orderData['addresses'] = self::$addresses->fetchAll(['purchase_order_id = ?' => $row->id])->toArray();
$results[] = $orderData;
}
方法3(最小化查询和排序数据,1000条记录~10秒)
$orderRows = $this->fetchSearchResults($searchParams);
$orderIds = array_column($orderRows->toarray(), 'id');
$itemRows = self::$items->fetchAll(['purchase_order_id IN (?)' => array_values($orderIds)]);
$addressRows = self::$addresses->fetchAll(['purchase_order_id IN (?)' => array_values($orderIds)]);
$searchResults = array_map(function($order) use($itemsRows, $addressRows) {
$order['contents'] = array_filter($itemsRows->toArray(), function($itemRow) use($order){
return ($itemRow['purchase_order_id'] === $order['id']);
});
$order['addresses'] = array_filter($addressRows->toArray(), function($addressRow) use($order){
return ($addressRow['purchase_order_id'] === $order['id']);
});
return $order;
}, $orderRows->toArray());
我很惊讶地看到使用array_*
函数对数据集进行排序比#"方法2"尽管消除了大约2000个查询,并且比使用Zend的findDependentRowset
如何加快这些查询速度?是否有办法在单个查询中检索订单及其所有项目和地址?