2014-03-04 3 views
1
SELECT DISTINCT 
viewA.TRID, 
viewA.hits, 
viewA.department, 
viewA.admin, 
viewA.publisher, 
viewA.employee, 
viewA.logincount, 
viewA.registrationdate, 
viewA.firstlogin, 
viewA.lastlogin, 
viewA.`month`, 
viewA.`year`, 
viewA.businesscategory, 
viewA.mail, 
viewA.givenname, 
viewA.sn, 
viewA.departmentnumber, 
viewA.sa_title, 
viewA.title, 
viewA.supemail, 
viewA.regionname 
FROM 
viewA 
LEFT JOIN viewB ON viewA.TRID = viewB.TRID 
WHERE viewB.TRID IS NULL 

약 10K 및 5K 개의 레코드가있는 두 개의보기가 있습니다. 그들은 각각 아주 빨리 들어갑니다. ViewA에서 ViewB에없는 모든 레코드를 가져 오려고하면 작동하지만 매우 느립니다. 기본 TRID 필드는 모두 동일한 문자 집합이며 모두 varchar (10)로 설정되고 인덱싱 된 테이블은 모두 Innodb입니다. 지금 쿼리가 16 초 걸립니다. 내가 할 수있는 건 뭐니?두 개의보기를 결합하면 왼쪽이 느립니까?

+0

왼쪽 결합을 제거하고 결합을 시도 했습니까? – DevelopmentIsMyPassion

+0

@AshReva - 매우 빠르지 만 반환 값은 없습니다. – blankip

+0

평균적으로 얼마나 많은 레코드가 반환됩니까? 두 번째보기 뒤의 쿼리는 어떤 모양입니까? –

답변

4

일반적으로 JOIN으로 MySQL은 각 결합 된 레코드에 대해 조회를 수행해야합니다. 조회는 키를 사용할 때 빠르지 만, 귀하의 경우 조인 된 테이블이보기이기 때문에 실제적으로 키가 없습니다.

첫 번째보기에서 레코드 당 한 번씩 두 번째보기 뒤에서 쿼리를 실행하지 않도록 MySQL에서 하위 쿼리를 사용할 수 있습니다.

SELECT * 
FROM viewA 
WHERE TRID NOT IN (SELECT TRID FROM viewB); 

는 MySQL은 다음 viewA의 각 레코드에 대한 그들에 검색을 할 (임시 테이블) 하위 쿼리에 viewB에 대한 모든 TRID 값을 얻을 수 있도록해야한다.

MySQL docs에서

:

MySQL은 한 번만 상관 하위 쿼리를 실행합니다. EXPLAIN을 사용하여 이 주어진 하위 쿼리가 실제로 상관 관계가 없다는 것을 확인하십시오.

+0

분명히 당신은'NOT' 키워드를 원하지 않았습니까? OP는'TRID IS NULL'을 사용하여 레코드를 얻으려고 필터링하고 있으므로'TRID NOT IN (SELECT TRID FROM viewB)'를'TRID IS NULL' (Robert의 답)으로 대체 할 수도 있습니다. –

+2

@DavidKnipe, 원래 쿼리를 다시 읽었으며 여전히 NOT IN이 맞다고 생각합니다. –

+0

'NULL IN (...)'이'NULL '이기 때문에 false로 평가되는 SQL의 이상한 점이 없으면 (나는 NULL이라는 것을 기억한다.) 로버트의 해결책이 더 좋다면, 어쨌든 그것은 논점이 아닙니다. –

0

MySQL에서보기를 사용하여 쿼리를 최적화하는 것은 어렵습니다. 나의 첫 번째 제안은 그것이 필요하다는 것을 절대적으로 알지 못한다면 distinct을 제거하는 것입니다.

select viewA.* 
from viewA 
where not exists (select 1 from viewB where viewB.TRID = viewA.TRID); 

하나가 다른 것보다 더 좋을 것입니다 여부를 말하기 어렵지만, 이것이 더 있는지 확인하기 위해 노력하고 가치가있다 :

그런 다음이 쿼리 성능을 비교 수 있습니다.

+0

약 0.5 초 정도 걸립니다. DB를 잘못 설정하고 있습니까? 이러한 하위 집합은 매우 비공식 적입니다 (규칙을 나타내는 필드가 없지만 일련의 규칙과 사례를 사용하여 만들어 짐) 주로보고 용도로 사용됩니다. – blankip

+0

@ blankankip. . . 색인이 도움이 될 수 있습니다. 그러나 일어나는 일은'viewB'가 빨리 실행된다는 것입니다. 그런 다음 'viewA'와 결합하려면 느린 결합을 수행해야합니다. 이 두 SQL 문과 함께 뷰의 내용과 테이블의 모든 인덱스를 포함하는 또 다른 질문을 할 수 있습니다. 그렇다면 이것이 어떻게 최적화 될 수 있는지 질문하십시오. 나는 이미 여러 답을 가지고 있기 때문에이 질문을 다시 쓰는 것이 불공평하다고 생각합니다. –

관련 문제