Mysql-запрос с левым соединением слишком медленно - PullRequest
8 голосов
/ 15 июля 2010

Запрос:

   select `r`.`id` as `id` 
     from `tbl_rls` as `r` 
left join `tblc_comment_manager` as `cm` on `cm`.`rlsc_id` != `r`.`id`

Обе таблицы содержат 8 тыс. Записей, но почему это очень медленно, иногда занимает 2-3 минуты и более?

OMG, этот запрос отключает MySQL-сервер.Люди вернутся к вам через секунду: (

Все люди, которые предложили Индексировать столбцы, все Правильны. Да, мой запрос был глупым и ошибочным. Спасибо, исправляете меня.

Ответы [ 6 ]

21 голосов
/ 15 июля 2010

Рассмотрим также индексацию ваших таблиц. Мы выполняем несколько левых объединений в таблице записей на 1 миллион +, для возврата результатов которой требуется не более секунды или двух.

13 голосов
/ 15 июля 2010

Вам действительно нужен != или он должен быть =?

 select `r`.`id` as `id` from `tbl_rls` as `r` 
  left join `tblc_comment_manager` as `cm` 
on  `cm`.`rlsc_id`!=`r`.`id

Это выберет почти декартово произведение из 2 таблиц.(Я предполагаю, около 60 миллионов строк)

Редактировать: Из комментария

да, это "! =", Чтобы соответствовать tbl_rls.id те, которые не находятся вtblc_comment_manager

Я думаю, это то, что вам нужно, если вы хотите использовать подход outer join.

 select DISTINCT `r`.`id` as `id` from `tbl_rls` as `r` 
  left join `tblc_comment_manager` as `cm` 
on  `cm`.`rlsc_id`=`r`.`id
WHERE `cm`.`rlsc_id` IS NULL

Хотя обычно я предпочитаю

 select `r`.`id` as `id` 
 from `tbl_rls`
 as `r` 
 WHERE NOT EXISTS(
          SELECT * FROM `tblc_comment_manager` as `cm` 
          WHERE  `cm`.`rlsc_id`=`r`.`id)
4 голосов
/ 15 июля 2010

Что вы хотите выбрать?

Используйте этот запрос, если вы хотите найти записи tbl_rls, которые не соответствуют записям в другой таблице

select `r`.`id`
from `tbl_rls` as `r` 
left join `tblc_comment_manager` as `cm` 
    on  `cm`.`rlsc_id`=`r`.`id
where `cm`.`rlsc_id` IS NULL
2 голосов
/ 15 июля 2010

Возможно, вам потребуется предоставить больше информации.Но я бы попытался изменить порядок предложения ON (потому что это так просто):

ON r.id != cm.rlsc_id

Edit: и вы должны поместить индексы в свой PK (id) columns.

Но я думаю эта статья может вам помочь .

В основном говорится, что NOT IN требует меньше ресурсов, чем LEFT JOIN.Комментатор в этой статье упоминает, что лучше использовать NOT EXISTS.

Кроме того, я не уверен, что это верно или нет, но в этой статье говорится, что NOT IN выполняет полное сканирование таблицы, иNOT EXISTS можно использовать индекс .

2 голосов
/ 15 июля 2010

MySQL EXPLAIN может помочь вам узнать, что происходит.

1 голос
/ 15 июля 2010

Похоже, вам нужны значения r.id, которых нет в таблице tblc_comment_manager.

Используйте Not In

, выберите r. id как id
из tbl_rls как r
, где r. id не в (выберите отличительные cm. rlsc_id из tblc_comment_manager как cm)

...