优化对聚合的搜索结果的检索

I'm using Zend Framework 1.11 and trying to speed up the retrieval of model data for the client application. I've tried three approaches, each of them being roughly the same speed which has me stumped.

For this example, I am retrieving Purchase Orders along with their Items and all associated Address records. The data is spread across three tables: purchase_orders, purchase_order_items and purchase_order_addresses.

The schema is as you would expect:

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.

Method 1 (findDependentRowset) - 1000 records in ~12 seconds

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;
}

Method 2 (nested SQL queries, 1000 records ~9 seconds)

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;
}

Method 3 (minimize queries and sort data, 1000 records ~10 seconds)

$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());

I was surprised to see that sorting the data set using array_* functions was slower than "method 2" despite eliminating ~2000 queries and barely faster than using Zend's findDependentRowset

How can I speed these queries up? Would there be a way to, in a single query, retrieve the Order along with all of its Items and Addresses?