2009-12-25 2 views
2

한 테이블에서 다른 테이블에없는 값을 찾는 쿼리를 수행하고 있습니다. 예를 들어 :MySQL 쿼리 최적화

SELECT id FROM table1 WHERE id NOT IN (SELECT id FROM table2); 

두 테이블은 약 1 백만 행하지만이 결과 집합에 반환되는 값과 일치하지 않는 단지 몇 백. 쿼리는 약 35 초가 걸립니다. 쿼리에서 쇼 프로필을 수행하면 mysql이 "준비 중"상태로 대부분의 시간을 보내고 있음을 알 수 있습니다. 이 상태를 어떻게 최적화 할 수 있는지 또는 "준비 중"실제로 일어나고있는 것에 대한 아이디어는 있습니까?

두 테이블의 id 값은 색인화되었으며 동일한 유형 및 크기입니다.

질의의 전체 프로파일은 다음

+--------------------------------+----------+ 
| Status       | Duration | 
+--------------------------------+----------+ 
| (initialization)    | 0  | 
| checking query cache for query | 0  | 
| Opening tables     | 0.13  | 
| System lock     | 0  | 
| Table lock      | 0  | 
| init       | 0.01  | 
| optimizing      | 0  | 
| statistics      | 0  | 
| preparing      | 0  | 
| executing      | 0  | 
| Sending data     | 0  | 
| optimizing      | 0  | 
| statistics      | 0  | 
| preparing      | 34.83 | 
| end       | 0  | 
| query end      | 0  | 
| freeing items     | 0  | 
| closing tables     | 0  | 
| logging slow query    | 0  | 
+--------------------------------+----------+ 

모든 팁이 이해된다.

감사합니다.

답변

3

id가 null 인 테이블에 join2를 남겨 둡니다. 이렇게하면 데이터를 훨씬 빨리 반환 할 수 있습니다.

select 
    a.id 
from 
    table1 a 
    left join table2 b on a.id = b.id and b.id is null 
+0

바로 왼쪽에 조인 chnaged 기쁘다! –

+0

b.id가 null이어야하며 어디에 사용해야합니까? –

+0

where 절에서이를 지정하는 것이 바람직합니다. 옵티마이 저는 동일한 계획을 세워야합니다. –

1
SELECT id FROM table1 
LEFT JOIN table2 ON table1.id = table2.id 
WHERE table2.id IS NULL; 
+0

쿼리는 여전히 약 30 초 걸리지 만이 "show profile ; " 대부분의 시간은 "데이터 전송"에 있습니다. 그것은 mysql이 쿼리를 실행하는 데 걸리는 시간일까요, 아니면 속도를 높이기 위해 할 수있는 일이 있습니까? –

+0

정의한 색인에 따라 달라집니다 ... –

2

최적화 거기에 아무것도 - NOT IN는 MySQL의에서 LEFT JOIN/IS NULL에 해당하는 쿼리 계획을 생성합니다. 인용구 :

그러나이 세 가지 방법은 서로 다른 세 가지 코드로 실행되는 세 가지 다른 계획을 생성합니다. EXISTS 술어를 실행하는 코드는 index_subquery 및 LEFT JOIN을 실행하는 코드가 Not exists 메소드를 사용하도록 최적화 된 코드보다 약 30 % 덜 효율적입니다.

MySQL에서 누락 된 값을 검색하는 가장 좋은 방법은 존재하지 않는 것보다 LEFT JOIN/IS NULL 또는 NOT IN을 사용하는 것입니다.

자세한 내용은

참조 NOT IN vs. NOT EXISTS vs. LEFT JOIN/IS NULL: MySQL

+0

동등한 검색어를 생성하려면'table2.id' 색인이 생성되어야합니다. 그러나 그 이름 (PK와 같은 소리)과 쿼리가'1,000,000 '행에 대해 35 초를 소비한다는 사실로부터 우리는 그것이 색인 된 것으로 결론을 내릴 수 있습니다. – Quassnoi