두 가지 쿼리가 비슷하지만 성능이 매우 다르기 때문에 그 이유를 파악할 수 없습니다. 기본적으로, 나는 잠그고 처리해야하는 큰 테이블 (6M 행)의 블로그를 가지고있다. 원래 쿼리는이 모습이의MySql 쿼리 성능 퍼즐
insert into bloglock
select b.id, [lockid], CURRENT_TIMESTAMP
from blog b
left join bloglock bl
on b.id=bl.blogid
WHERE
State=[somestate]
AND
bl.BlogId IS NULL
의미는 다음과 같습니다 블로그 ID, 잠금 ID 및 현재의 타임 스탬프로 구성된 bloglock 테이블의 항목을 만들어 블로그를 잠금 . 그러나 블로그 상태가 우리가 잠그고 자하는 것이고, 블로그가 이미 잠겨 있지 않은 경우에만 (bl.BlogId가 NULL 임)이 작업을 수행하십시오.
이 쿼리는 약 5/100 초의 속도로 매우 빠르게 실행됩니다.
하지만 다른 블로그보다 먼저 특정 블로그를 처리해야했습니다. 그래서이 분야에 인덱스를 정수 우선 순위 필드를 추가하고 쿼리를 변경 :이 우선 순위에 처음 100 백을 얻는 것을 제외하고, 이전과
insert into bloglock
select b.id, [lockid], CURRENT_TIMESTAMP
from blog b
left join bloglock bl
on b.id=bl.blogid
WHERE
State=[somestate]
AND
bl.BlogId IS NULL
order by Priority desc
LIMIT 100;
동일합니다. 이 쿼리는 실행 속도가 약 30 초 정도되는 개가 느립니다. 나는 그것을 받아 들일 수있다. 그러나 퍼즐은 내가 이것을 다음과 같이 다시 썼다는 것입니다.
insert into bloglock
select *
from
(select b.id, [lockid], CURRENT_TIMESTAMP
from blog b
left join bloglock bl
on b.id=bl.blogid
WHERE
State=[somestate]
AND
bl.BlogId IS NULL
order by Priority desc
LIMIT 100) InnerQuery;
이제는 이전과 같이 빠르게 실행됩니다. 나는 이것을 얻지 못한다. 나에게도 같은 쿼리 인 것 같아요. 물론 옵티마이 저가 동일하다고 생각 하겠지만 대신 성능에 60 배의 차이가 있습니다. 무슨 일 이니?
실제 답변에 기여할만큼 잘 이해하지 못 하겠지만, 'LIMIT' 절의 위치가 작업을 수행하고 있다고 생각합니다. 첫 번째 사례의 끝에서 100까지 필터링하고 있습니다. 두 번째로는 처음에는 100으로 (할 일을 크게 줄임). – girasquid
두 쿼리의 explain 계획을 살펴 보았습니까? – HLGEM
@ 루케 : 두 경우 모두 괄호로 작업을 동일한 방식으로 그룹화했다면 어떻게 될지 모르겠다. –