我从非常大的问题表(600,000条记录)中得到Question
模型,与Customer
,Answer
和Product
模型有关。关系与这个问题无关,但我提到他们澄清我需要使用Eloquent。当我致电Question::with('customer')->get();
时,它会平稳而快速地运行。
但还有另一张表格,其中question_id
所有问题都不应该显示(出于特定原因)。
我试过这段代码:
// omitted product ids, about 95,000 records
$question_ids_in_product = DB::table('question_to_product')
->pluck('product_id')->all();
$questions = Question::with('customer')
->whereNotIn('product_id', $question_ids_in_product)
->paginate($perPage)->get();
需要花费很多时间并显示此错误:
SQLSTATE[HY000]: General error: 1390 Prepared statement contains too many placeholders
有时Fatal error: Maximum execution time of 30 seconds exceeded
当我使用普通的sql查询运行它时:
SELECT * FROM questions LEFT JOIN customers USING (customer_id)
WHERE question_id NOT IN (SELECT question_id FROM question_to_product)
它只需要80毫秒
在这种情况下如何使用Eloquent?
答案 0 :(得分:2)
您可以使用whereRaw方法:
/* 1 */
{
"_id" : {
"client" : "symphony"
},
"clientIdCount" : 4,
"numberOfUsers" : 3
}
/* 2 */
{
"_id" : {
"client" : "merlin"
},
"clientIdCount" : 3,
"numberOfUsers" : 2
}
但理想情况下,您发现这是一种更好的解决方案:
$questions = Question::with('customer')
->whereRaw('question_id NOT IN (SELECT question_id FROM question_to_product)')
->paginate($perPage)->get();
差异?
当您迁移您的数据库另一个数据库时,Question::with('customer')->whereNotIn('question_id',
function ($query) {
$query->from('question_to_product') ->select('question_id');
}
);
可能无法正常放入原始语句。
这就是为什么我们有Eloquent ORM来处理这些转换并构建适当的查询来运行。
没有性能影响,因为SQL是相同的(对于whereRaw
)
P.S:为了更好的调试,请尝试安装this debug bar
答案 1 :(得分:0)
参考https://laravel.com/docs/5.4/queries#where-clauses
$users = DB::table('questions')
->leftJoin('customers', 'curtomer.id', '=', 'question.user_id')
->whereNotIn('question_id', [1, 2, 3])
->get();