2017-10-17 11 views
4

관계에 where 조건을 적용하고 싶습니다. 여기에 내가 할 수있는 작업은 다음과 같습니다가난한 곳 Laravel의 성능이

Replay::whereHas('players', function ($query) { 
    $query->where('battletag_name', 'test'); 
})->limit(100); 

그것은 다음 쿼리를 생성하고 70 초 실행

select * from `replays` 
where exists (
    select * from `players` 
    where `replays`.`id` = `players`.`replay_id` 
     and `battletag_name` = 'test') 
order by `id` asc 
limit 100; 

합니다. 다음과 같이 수동으로 쿼리를 다시 작성하는 경우 :

select * from `replays` 
where id in (
    select replay_id from `players` 
    where `battletag_name` = 'test') 
order by `id` asc 
limit 100; 

0.4 초 후에 실행됩니다. 왜 느린 경우 where exists이 기본 동작입니까? 쿼리 작성기로 올바른 where in 쿼리를 생성하는 방법이 있습니까? 아니면 원시 SQL을 주입해야합니까? 어쩌면 내가 뭔가 잘못하고있는 것일까?

replays 테이블에는 4M 행이 있고, players에는 40M 개의 행이 있으며, 모든 관련 열은 인덱스되며, 데이터 세트는 MySQL 서버 메모리에 맞지 않습니다.

업데이트 : 올바른 쿼리로 생성 할 수 있음을 발견 : exists 그렇게 가난하게 수행하고 기본 동작을 왜 왜

Replay::whereIn('id', function ($query) { 
    $query->select('replay_id')->from('players')->where('battletag_name', 'test'); 
})->limit(100); 

아직도 질문이

+0

에서 원시 쿼리 객체를 사용하지 않는 이유는 더 빠른 쿼리가 있다면 내가 * ..하려고 SELECT 말아 제안 모두 대신 특정 속성을 선택하십시오. – parkway

+0

제 경우에는 모두 선택해야합니다. 그리고'id' 컬럼 만 선택해도 쿼리 성능이 1 % 이하로 향상되므로 무시할 수 있습니다. – Poma

답변

1

나는 성능이하지 않는 생각 어디 까지나 얼마나 많은 레코드를 사용 하느냐에 따라 달라집니다.

플러스 mysql 서버를 최적화하려고 시도했습니다.

https://dev.mysql.com/doc/refman/5.7/en/optimize-overview.html

또한 당신의 PHP 서버

을 최적화하고 당신이 애벌레

$replay = DB::select('select * from replays where id in (
select replay_id from players where battletag_name = ?) 
order by id asc limit 100', ['test'] 
); 
+0

두 쿼리는'limit' 절로 인해 정확히 100 개의 행을 선택합니다. 어디서 70 초, 어디서 0.4 초입니까? 최적화는 두 쿼리 실행 시간을 줄이기 때문에 질문과 관련이 없습니다. – Poma

+0

어쩌면 당신은 실제 응용 프로그램에서 위에서 언급 한 원시 쿼리를 –

+0

쿼리를 사용할 수있는 것은 많은 조건을 가진 것보다 더 복잡한 방법이며 실제로 쿼리 작성기가 필요합니다. 원시 문자열 부분을 많이 만들면 코드가 스파게티가됩니다. – Poma