2017-01-05 5 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'); 
     } 
    } 

Как вы можете видеть, что есть hasMany соотношение между Conversation и Question моделей.

В базе данных 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 и WAMP 3.0.6 (Apache 2.4.23 - PHP 5.6.25/7.0.10 - MySQL 5.7.14) на Windows 8, 64 битную.

В чем проблема? Что я могу сделать?

UPDATE:
добавить индекс первичных ключей и внешних ключей на двух столах и все работало нормально.

+0

Что делает 'dd ($ conversations-> toSql())' дал вам? (поместите этот 'dd (..)' в строку непосредственно перед '$ conversations-> paginate (5);') –

+0

@BagusTesa, который возвратил ** «выберите * из' цепочек', где существует (выберите * из 'вопросов 'где' questions'.'conversation_id' = 'conversations'.'conversation_id' и' text' LIKE? и 'is_private' =? и' answer' <>? и ('подтверждено' =? или' подтверждено_expert_admin_at' <=?) и 'questions'.'deleted_at' равно null) и' беседы'.'deleted_at' имеет нулевой порядок' created_at' desc ** ** –

+3

@ABDeveloper пытается запустить этот запрос в 'phpadmin' или что-то, чтобы увидеть, является ли проблема mysql. Посмотрите, индексированы ли все' id '. другая система, так как авария может быть из-за вашего экземпляра mysql. –

ответ

0

Попробуйте этот. Добавить with() до того, гдеHas.

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()); 
      }); 
    } 
}]); 

Попробуйте это и проверьте, снижена ли загрузка сервера.