我有一个看起来像的数据库:
联系人
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);
哪个有效。
它会返回bob
和jill
。
然而它没有非常优化,因为它有一个从属子查询。任何人都可以帮助优化它吗?
答案 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 nullable,NOT 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)的索引。