为什么Eloquent有whereHas方法使用子查询而不是连接?

时间:2015-01-28 04:25:52

标签: php laravel laravel-4 eloquent

为什么Laravel使用子查询来执行Eloquent haswhereHas方法而不是使用连接?例如,我构建了一个像这样的Eloquent查询:

Order::whereHas('orderProducts', function($query)
{
        $query->where('product_id', $this->id);

})
->whereHas('status', function($query)
{
        $query->where('sales_data', 1);

})
->where('ext_created_at', '>=', $startDate)
->where('ext_created_at', '<=', $endDate.' 23:59:59')
->distinct()
->count('id');

生成的查询是:

select count(distinct `id`) as aggregate from `orders` where `orders`.`deleted_at` is null and (select count(*) from `order_products` where `order_products`.`order_id` = `orders`.`id` and `product_id` = ? and `order_products`.`deleted_at` is null) >= 1 and (select count(*) from `order_statuses` where `orders`.`order_status_id` = `order_statuses`.`id` and `sales_data` = ? and `order_statuses`.`deleted_at` is null) >= 1 and `ext_created_at` >= ? and `ext_created_at` <= ?

此查询返回16的结果。根据{{​​1}},这需要执行DB::getQueryLog()

然后我构建了另一个这样的查询:

23222.14 ms

生成的查询是:

DB::table('orders')
    ->leftJoin('order_products', 'orders.id', '=', 'order_products.order_id')
    ->leftJoin('order_statuses', 'orders.order_status_id', '=', 'order_statuses.id')
    ->whereNull('orders.deleted_at')
    ->where('order_products.product_id', $this->id)
    ->where('orders.ext_created_at', '>=', $startDate)
    ->where('orders.ext_created_at', '<=', $endDate.' 23:59:59')
    ->whereNull('order_products.deleted_at')
    ->where('order_statuses.sales_data', 1)
    ->distinct()
    ->count('orders.id')

此查询还会返回select count(distinct `orders`.`id`) as aggregate from `orders` left join `order_products` on `orders`.`id` = `order_products`.`order_id` left join `order_statuses` on `orders`.`order_status_id` = `order_statuses`.`id` where `orders`.`deleted_at` is null and `order_products`.`product_id` = ? and `orders`.`ext_created_at` >= ? and `orders`.`ext_created_at` <= ? and `order_products`.`deleted_at` is null and `order_statuses`.`sales_data` = ? ,但需要16才能运行。显然,使用连接在这里有更好的性能,但是这只是特定于我的用例,还是加入通常更好的性能?如果是这样,为什么Eloquent不会在子查询中使用连接?我更愿意使用模型并使用所有优秀的Eloquent方法,如3.52 mshas,但性能是如此显着不同,我被迫使用查询生成器自己构建查询

我在这里错过了什么吗?

我正在使用whereHas

0 个答案:

没有答案