Запрос Mysql с левым соединением слишком медленный

Запрос:

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

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

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

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


person Arshdeep    schedule 15.07.2010    source источник
comment
Есть индексы? Если да, то на каких столбцах?   -  person middus    schedule 15.07.2010
comment
Оба столбца id должны иметь индексы   -  person JohnB    schedule 15.07.2010


Ответы (6)


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

person bpeterson76    schedule 15.07.2010
comment
Черт возьми, это был виновник. Я пошел от 10 минут до 0,9 мс. Любая рекомендация по инструменту анализа MySQL, который может сказать вам, какие индексы вы должны иметь в своей базе данных? - person Joshua Pinter; 16.08.2017
comment
Индексация сделала свое дело. теперь запрос выполняется за 233 мс, а раньше — за 48 с. - person Kxng Kombian; 07.12.2020

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

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

Это выберет почти декартово произведение двух таблиц. (Я думаю, около 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)
person Martin Smith    schedule 15.07.2010
comment
да, это != чтобы соответствовать tbl_rls.id тем, которых нет в tblc_comment_manager - person Arshdeep; 15.07.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
person Naktibalda    schedule 15.07.2010

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

person middus    schedule 15.07.2010
comment
похоже, это должен быть комментарий - person treyBake; 09.09.2019

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

ON r.id != cm.rlsc_id

Изменить: и вы должны поместить индексы в столбцы PK (id).

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

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

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

person JohnB    schedule 15.07.2010
comment
@JohnB Для SQL Server «NOT IN» и NOT EXISTS более эффективны (хотя необходимо соблюдать осторожность в отношении NULL для первого). Для MySQL я не уверен, какова рекомендация. - person Martin Smith; 15.07.2010
comment
Кроме того, другие указали на подход: WHERE cm.rlsc_id IS NULL - person JohnB; 15.07.2010
comment
@Martin: тот, кто читал Высокопроизводительный MySQL, может знать ответ - amazon.com/High-Performance-MySQL-Jeremy-Zawodny/dp/0596003064 - person JohnB; 15.07.2010
comment
Тем не менее, у него есть несколько вариантов, на проверку которых у него уйдет 5 минут. Arsheep, пожалуйста, опубликуйте свои результаты! - person JohnB; 15.07.2010
comment
@Martin: когда вы делаете столбец PK в MySQL, он автоматически создает индекс для этого столбца? Если нет, создайте индексы для ваших столбцов PK Arsheep! - person JohnB; 15.07.2010
comment
@JohnB - Да, быстрый тест на этом конце, похоже, говорит, что вы автоматически получите индекс для ПК, но я думаю, что это может не помочь tblc_comment_manager - person Martin Smith; 15.07.2010
comment
@Martin Smith: зависит от того, являются ли столбцы nullable или нет - person OMG Ponies; 15.07.2010

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

Используйте не в

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

person DaveWilliamson    schedule 15.07.2010