2017-08-08 96 views
0

我有一个Question模型从非常大的问题表(600,000记录),与Customer,AnswerProduct模型。关系与这个问题无关,但我提到他们澄清我需要使用雄辩。当我打电话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毫秒

如何在这种情况下使用雄辩?

回答

2

是指可以使用whereRaw方法:

$questions = Question::with('customer') 
       ->whereRaw('question_id NOT IN (SELECT question_id FROM question_to_product)') 
       ->paginate($perPage)->get(); 

但最好你发现这是一个更好sollution:

Question::with('customer')->whereNotIn('question_id', 
    function ($query) { 
     $query->from('question_to_product') ->select('question_id'); 
    } 
); 

区别?

  1. 当你将您的数据库迁移到另一个数据库你把原始报表whereRaw可能无法正常工作。 这就是为什么我们有雄辩的ORM来处理这些转换并建立适当的查询来运行。

  2. 性能没有影响,因为SQL是相同(MySQL

P.S:为了更好的调试尝试安装this debug bar

+0

这是一个很好的解决方案。它花了约1.7秒。当我使用这个代码时花了600毫秒。问题:: with('customer') - > whereNotIn('question_id',function($ query){'question_to_product') - > select('question_id'); });''有什么不同? – Hadu

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(); 
+0

在whereNotIn阵列具有超过90,000项。这个错误信息是因为它:SQLSTATE [HY000]:一般错误:1390准备语句包含太多占位符 – Hadu