2017-12-27 4 views
2

나는 다음과 같은 쿼리가 : 순서를 사용하여 때MySQL의 순서가 느린 해결하지만, 확실하지 왜

select * 
from 
    `twitter_posts` 
where 
    `main_handle_id` in (
    select 
     `twitter`.`main_handle_id` 
    from 
     `users` 
     inner join `twitter` on `twitter`.`user_id` = `user`.`id` 
    where 
     `users` LIKE 'foo' 
) 
order by created_at 

이 쿼리가 극적으로 느리게 실행됩니다. twitter_posts 테이블에는 created_at 타임 스탬프와 main_handle_id 열에 대한 인덱스가 있습니다.

"설명"을 사용하여 엔진이 수행 할 계획을 확인하고 파일롯을 발견했습니다 ... twitter_posts 테이블에 인덱스로 볼 것으로 예상하지 못했습니다. Stackoverflow와 블로그에서 이것을 다루는 여러 게시물을 감추고 나서, 어떤 예제도 나에게 도움이되지 못했다. 내가 직감을 가졌다면 SQL Optimizer가 중첩 된 선택과 어떻게 든 혼란 스러울 수 있습니다. 그래서 쿼리를 싸서 created_at하여 해당 결과를 정렬 :

select * (select * 
from 
    `twitter_posts` 
where 
    `main_handle_id` in (
    select 
     `twitter`.`main_handle_id` 
    from 
     `users` 
     inner join `twitter` on `twitter`.`user_id` = `user`.`id` 
    where 
     `users` LIKE 'foo' 
) 
) 
order by created_at 

이 하나를 설명하여, 정렬 인덱스를 사용 하는가하고 filesort로가는 무슨의 일부분에 응답을 반환합니다. 그래서 저는 문제를 "해결했습니다"그러나 SQL이 솔루션을 기반으로 다른 선택을하게되는 이유를 이해하지 못합니다. 내가 볼 수있는 한, 결과를 래핑하고 그 결과의 모든 것을 궁극적으로 중복 된 문장으로 묻는 것입니다 ...

편집 : 나는 왜 optimizer가 created_at에서 색인을 사용하기 시작했는지 아직도 알지 못합니다. 중복 하위 쿼리를 사용할 때가 있지만 어떤 경우에는 더 빠르지 않았습니다. 이제는 "FORCE INDEX FOR ORDER BY created_at_index_name"문을 추가하는 솔루션을 사용했습니다.

+0

강제 색인을 사용해 보셨습니까? –

+0

나는 참을성이 있지만 그것도 효과가 없으며 조금 더러운 해결책이다 ...중복 쿼리도 그렇지만 :) 그럼 내 질문은 어떻게 최적화 할 수있는 해결책이 아닌가하는 것입니다. 제 질문은 그 이유입니다. 나는 그 대답이 내가 사용하는 MariaDB 버전에 매우 잘 좌우 될 것이라고 생각한다. 내가 MySQL과 마리아 사이에 중요한 최적화 변경을 알지 못합니다 ... –

+0

@ PraveenE 중복 선택과 함께 일하는 내 대답을 업데이 트했습니다 일부 쿼리에있는 임시 테이블이 발생합니다 (내부에 따라 문장)은 느려지기도합니다. –

답변

1

IN (SELECT ...); 이것을 JOIN으로 변환하십시오. 또는 EXISTS (SELECT ...)으로 변환하면 성능이 더 좋아질 수 있습니다.

EXPLAINs을 제공해주십시오. 둘 다 동일하더라도입니다. 사용중인 버전에 해당하는 경우 EXPLAIN FORMAT=JSON SELECT ...을 입력하십시오.

최적화 프로그램을 중첩 쿼리로 혼동하면 왜 다른 중첩을 추가해야합니까 ??

어느 테이블이 users입니까?

귀하는 user.id을 언급했지만 FROM 또는 JOIN에는 user 표가 없습니다.

어떤 버전의 MySQL (또는 MariaDB)를 사용하고 있습니까? 5.6 및 특히 5.7은 MariaDB와 관련하여 옵티 마이저에 중요한 차이가 있습니다.

쿼리에 언급 된 각 테이블에 SHOW CREATE TABLE을 제공하십시오.

의견에 귀하가 제시 한 질문이 도움이되지 않는다는 힌트가 있습니다. 자체가 아닌 쿼리에 대해 질문하지 마십시오.

아, users.name입니까? 적합한 색인이 있는지 보려면 CREATE TABLEs을 참조하십시오.

MariaDB가 언급되었으므로이 태그를 추가합니다. (아마도 이것은 특정 MariaDB 전문 지식을 가진 사람을 얻는 유일한 방법 일 것입니다.)