2017-01-05 25 views
0

我有一個Conversation模式是這樣的:運行whereHas大型數據集落laravel方法的mysql

class Conversation extends Model 
{ 
     use SoftDeletes; 

     protected $primaryKey = 'conversation_id'; 
     protected $dates  = ['deleted_at', 'expert_read_at', 'expert_admin_read_at']; 
     protected $fillable = ['code', 'expert', 'expert_read_at', 'expert_admin', 'expert_admin_read_at']; 

     public function questions(){ 
      return $this->hasMany('App\Question','conversation_id','conversation_id'); 
     } 
} 

而且一個問題模型是這樣的:

class Question extends Model 
    { 
     use SoftDeletes; 

     protected $primaryKey = 'question_id'; 
     protected $dates  = ['deleted_at', 'confirmed_expert_admin_at']; 
     protected $fillable = ['text', 'answer', 'conversation_id', 'confirmed', 'is_private', 'email', 'confirmed_expert_admin_at']; 

     public function conversation() 
     { 
      return $this->belongsTo('App\Conversation', 'conversation_id', 'conversation_id'); 
     } 
    } 

正如你可以看到有一個hasManyConversationQuestion型號之間的關係。

在MySQL數據庫中我有大約記錄Conversation和他們每個人至少有一個相關的Question

另一方面在前端有一個表格,用戶可以通過輸入文字來搜索問題text字段。

現在我想選擇至少有一個問題的對話根據用戶輸入,然後分頁結果。

對於我這樣寫道:

function SearchQuestion (Request $request) 
      { 
       $page   = $request->get('page'); 
       $questionPerPage = $request->get('question-per-page'); 
       $text   = $request->get('question-search-text'); 

       $conversations = 
        Conversation::whereHas('questions', function ($q) use ($text) { 
         if (!empty($text)) { 
          if (!is_numeric($text)) { 
           $q->where('text', 'LIKE', '%' . $text . '%') 
            ->where('is_private', 0) 
            ->where('answer', '<>', '') 
            ->where(function ($q1) { 
             $q1->where('confirmed', 1) 
              ->orWhere('confirmed_expert_admin_at', '<=', Carbon::now()->subDay()); 
            }); 
          } 
         } else { 
          $q 
           ->where('is_private', 0) 
           ->where('answer', '<>', '') 
           ->where(function ($q1) { 
            $q1->where('confirmed', 1) 
             ->orWhere('confirmed_expert_admin_at', '<=', Carbon::now()->subDay()); 
           }); 
         } 
        } 
        ); 

       if (!empty($text) and is_numeric($text)) { 
        $conversations->whereCode($text); 
       } 

       $conversations->orderBy('created_at', 'desc'); 

       $conversations = $conversations->paginate(5); 

       return $conversations; 
    } 

正如你可以看到我用了一個whereHas()方法在每個對話的問題進行搜索。

但每次我運行上面的查詢,在第一次嘗試時,這需要很長的時間來執行查詢有關12秒並在未來嘗試不返回任何結果和MySQL崩潰,我必須重新啓動WAMP。

但是,我想接下來要使用with() laravel方法選擇每個選定對話的問題。在這種情況下,我不知道執行查詢需要多長時間?

我使用laravel 5.3和瓦帕3.0.6(阿帕奇2.4.23 - PHP 25年5月6日/ 7.0.10 - MySQL的5.7.14)上的窗口8中,64位。

問題是什麼?我該怎麼辦?

UPDATE:
我添加索引,主鍵和兩個表的外鍵和所有的東西正常工作。

+0

dd($ conversations-> toSql())給了你什麼? (把'dd(..)'放在'$ conversations-> paginate(5);') –

+0

@BagusTesa之前的行上,返回**「select * from'conversations' where exists(select * from'questions ''where'questions'.'conversation_id'''''conversations'.'conversation_id' and'text' LIKE?and'is_private' =?and'answer' <>?and('confirmed' =?or'confirmed_expert_admin_at' <=? )和'questions'.'leleted_at'爲空)和'conversations'。'deleted_at'爲'created_at' desc'的空訂單** –

+3

@ABDeveloper嘗試在'phpadmin'中運行該查詢,或者查看mysql是否存在問題,看看是否所有的id都被索引。不同的系統可能會因爲你的mysql實例而崩潰 –

回答

0

試試這個。在哪裏添加with()

Conversation::with('questions')->whereHas('questions', function ($q) use ($text) { 
       //your conditions on questions rows 
    }); 
0

你可以嘗試適應Eagerloading這樣。

$conversations = Conversation::with(['questions' => function ($q) use ($text) { 
    if (!empty($text)) { 
     if (!is_numeric($text)) { 
      $q->where('text', 'LIKE', '%' . $text . '%') 
       ->where('is_private', 0) 
       ->where('answer', '<>', '') 
       ->where(function ($q1) { 
        $q1->where('confirmed', 1) 
         ->orWhere('confirmed_expert_admin_at', '<=', Carbon::now()->subDay()); 
       }); 
     } 
    } else { 
     $q 
      ->where('is_private', 0) 
      ->where('answer', '<>', '') 
      ->where(function ($q1) { 
       $q1->where('confirmed', 1) 
        ->orWhere('confirmed_expert_admin_at', '<=', Carbon::now()->subDay()); 
      }); 
    } 
}]); 

試試看看服務器負載是否降低。