更高效的sql查找不在连接表中的记录?

时间:2013-12-10 16:36:27

标签: mysql sql

我有:

_sms_users_
id

_join_smsuser_campaigns_
sms_user_id

我想拔出在join_smsuser_campaigns表中没有记录的sms_users(通过join_smsuser_campaigns.sms_user_id = sms_users.id关系)

我有sql:

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

编辑:

这是解释选择结果:

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上没有索引?

这需要大约5分钟才能运行,我看到有一条记录。有没有更有效的方法通过加入这样做?我的sql技能非常基础。

1 个答案:

答案 0 :(得分:1)

IN子句中包含许多项时,查询可能会变慢。请改用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