帮助编写SQL查询

时间:2011-02-24 00:19:05

标签: mysql sql query-optimization

我有一个看起来像的数据库:

联系人

id | name
1  | bob
2  | jack
3  | jill

contactsGroupLink

cId| gId
1  | 1
2  | 3
2  | 3
2  | 5
3  | 4

基本上,

联系人通过contactsGroupLink表中的条目链接到组。

联系人可能分为多个群组,但联系人只能在群组中一次。

我想写的查询是

select `name` 
  from contacts 
 where contact.id not in (select contactId 
                           from contactsGroupLink 
                          where groupId = 5);

哪个有效。 它会返回bobjill

然而它没有非常优化,因为它有一个从属子查询。任何人都可以帮助优化它吗?

2 个答案:

答案 0 :(得分:3)

因为两列都不可能是NULL,所以在MySQL (only) the best option is to use the LEFT JOIN/IS NULL

   SELECT c.name
     FROM CONTACTS c
LEFT JOIN CONTACTSGROUPLINK cgl ON cgl.contactid = c.id
                               AND cgl.groupid = 5
    WHERE cgl.contactid IS NULL

If the columns were nullableNOT EXISTS是更好的选择:

   SELECT c.name
     FROM CONTACTS c
    WHERE NOT EXISTS (SELECT NULL
                        FROM CONTACTSGROUPLINK cgl
                       WHERE cgl.contactid = c.id
                         AND cgl.groupid = 5)

CONTACTSGROUPLINK表中的两列应该是主键,它会自动索引列(从~5.0 +?)。否则,请确保将列编入索引。

答案 1 :(得分:0)

...

where not exists (
  select 1 from contactsGroupLink cgl
  where cgl.contactid = contact.id and cgl.groupid = 5
)

这应该有效地使用您已经拥有的contactsGroupLink(contactid,groupid)的索引。