2013-12-10 2 views
2

내가 가진 :더 효율적인 sql은 조인 테이블에없는 레코드를 찾으십니까?

_sms_users_ 
id 

_join_smsuser_campaigns_ 
sms_user_id 

내가

내가 가지고있는 (= join_smsuser_campaigns.sms_user_id를 통해 sms_users.id 관계)를 join_smsuser_campaigns 테이블에 레코드가없는 sms_users를 꺼내 싶습니다 는 SQL :

select * from sms_users where id not in (select sms_user_id from join_smsuser_campaigns); 

편집 : 여기

Explain 스의 Select 결과 :

mysql> explain select u.* from sms_users u left join join_smsuser_campaigns c on u.id = c.sms_user_id where c.sms_user_id is null; 
+----+-------------+-------+-------+---------------+-------------------------------------------------------------+---------+------+-------+--------------------------------------+ 
| id | select_type | table | type | possible_keys | key               | key_len | ref | rows | Extra        | 
+----+-------------+-------+-------+---------------+-------------------------------------------------------------+---------+------+-------+--------------------------------------+ 
| 1 | SIMPLE  | u  | ALL | NULL   | NULL              | NULL | NULL | 42303 |          | 
| 1 | SIMPLE  | c  | index | NULL   | index_join_smsuser_campaigns_on_campaign_id_and_sms_user_id | 8  | NULL | 30722 | Using where; Using index; Not exists | 
+----+-------------+-------+-------+---------------+-------------------------------------------------------------+---------+------+-------+--------------------------------------+ 

mysql> describe sms_users; 
+------------------------+------------+------+-----+---------+-------+ 
| Field     | Type  | Null | Key | Default | Extra | 
+------------------------+------------+------+-----+---------+-------+ 
| id      | int(11) | NO | PRI | NULL |  | 

mysql> describe join_smsuser_campaigns; 
+---------------------+------------------+------+-----+---------+-------+ 
| Field    | Type    | Null | Key | Default | Extra | 
+---------------------+------------------+------+-----+---------+-------+ 
| sms_user_id   | int(11)   | NO |  | NULL |  | 

가입시 sms_user_id에 대한 색인이 없다는 것이 problm처럼 보입니까?

실행하는 데 약 5 분이 걸리고 하나의 레코드가 있음을 알 수 있습니다. 조인을 통해보다 효율적인 방법이 있습니까? 내 SQL 기술은 꽤 기본입니다.

+0

당신의 쿼리가 잘되어야 참조하십시오. –

+0

색인을 추가 한 후 두 쿼리 (원본과 새 쿼리)는 몇 분의 1 초 안에 있습니다. 감사. 덕분에 –

답변

1

IN 절에 많은 항목이있을 때 쿼리 속도가 느려질 수 있습니다. 당신은`join_smsuser_campaigns (sms_user_id)`에 인덱스가 가정하는 left join 대신

select u.* 
from sms_users u 
left join join_smsuser_campaigns c on u.id = c.sms_user_id 
where c.sms_user_id is null 

this great join explanation

+0

. 쿼리가 더 빨라지는지 지금 확인하십시오. 당신이 보낸 링크는 훌륭합니다. –

+0

예, 약 20 % 빨랐습니다. 감사. –

+0

시간은 수 밀리 초 정도 소요됩니다. 'explain select ... '를 실행하여 쿼리가 인덱스를 사용하지 않는 곳을 확인하십시오. –

관련 문제