优化汇总

时间:2016-01-20 17:40:58

标签: php mysql performance zend-framework

我正在使用Zend Framework 1.11并尝试加速检索客户端应用程序的模型数据。我尝试了三种方法,每种方法的速度大致相同,让我难以接受。

对于此示例,我正在检索采购订单及其物料和所有相关的地址记录。数据分布在三个表格中:purchase_orderspurchase_order_itemspurchase_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

快得多

如何加快这些查询速度?是否有办法在单个查询中检索订单及其所有项目和地址?

0 个答案:

没有答案