помогите написать запрос sql - PullRequest
1 голос
/ 24 февраля 2011

У меня есть база данных, которая выглядит следующим образом:

контакты

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.

однако он не очень оптимизирован, поскольку имеет зависимый подзапрос. кто-нибудь может помочь оптимизировать его?

Ответы [ 2 ]

3 голосов
/ 24 февраля 2011

Поскольку оба столбца, скорее всего, не равны NULL, в MySQL ( только ) наилучшим вариантом является использование 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

Если столбцы обнуляются , 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 +?). В противном случае убедитесь, что столбцы проиндексированы.

0 голосов
/ 24 февраля 2011

...

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

Это должно эффективно использовать индекс по уже имеющимся у вас контактам GroupGroupLink (contactid, groupid).

...