我正在使用Laravel 5.4
我有3个型号:Order,OrderLine和Product。
订单hasMany()OrderLines OrderLine hasOne()产品通过OrderLine模型中的product_id(我已经正确索引了这个,至少我认为!)
我的要求是检索产品所针对的某个品牌名称的所有订单和订单线。
这是我雄辩的查询。我知道查询有效,但是当放在大型数据集上时(大约10,000个订单,12,000个OrderLines / Products),它似乎无限运行
$orders = Order::whereBetween('order_date', [$this->start_date,$this->end_date])
->whereHas('lines', function ($q1){
$q1->whereHas('product', function ($q2){
$q2->where('brand', 'Brands>SanDisk');
});
})->with('lines')->with('lines.product')->get()->toArray();
通过toSql()方法调试时,会生成以下SQL。
select
*
from `orders`
where
`order_date` between ? and ?
and
exists (select * from `order_lines` where `orders`.`id` =`order_lines`.`order_id`
and
exists (select * from `products` where `order_lines`.`product_id` = `products`.`id` and `brand` = ?))
我创建表的3次迁移如下(为简单起见,除了键之外我已经删除了任何东西):
Schema::create('orders', function (Blueprint $table) {
$table->increments('id');
});
Schema::create('order_lines', function (Blueprint $table) {
$table->increments('id');
$table->integer('product_id');
$table->integer('order_id');
});
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
});
然后我添加了以下索引:
Schema::table('order_lines', function (Blueprint $table) {
$table->integer('product_id')->unsigned()->change();
$table->foreign('product_id')->references('id')->on('products');
});
EXPLAIN语法的结果如下:
1 PRIMARY orders ALL 91886 Using where
2 DEPENDENT SUBQUERY order_lines ALL 93166 Using where
3 DEPENDENT SUBQUERY products eq_ref PRIMARY PRIMARY 4 mymemory_main.order_lines.product_id 1 Using where
答案 0 :(得分:0)
尝试一下:
$orders = Order::query()
->whereBetween('order_date', [$this->start_date, $this->end_date])
->hasByNonDependentSubquery('lines.product', null, function ($q) {
$q->where('brand', 'Brands>SanDisk');
})
->with('lines.product')
->get()
->toArray();
仅此而已。口才快乐!