Альтернатива MySQL использованию двух вложенных запросов

Я пытаюсь узнать о соединениях MYSQL, но у меня возникают проблемы с этим. Я хочу получить все строки в таблице 1, где идентификатор пользователя находится во взаимосвязи с данным пользователем.

table2 содержит отношения пользователей, поэтому идентификатор пользователя может быть либо в поле iduser1, либо в поле iduser2. У меня есть следующий запрос, который дает мне правильные результаты:

set @userID = 91;
SELECT * FROM table1
    WHERE (iduser IN (SELECT iduser1 FROM table2 WHERE iduser2 = @userID)
        OR (iduser IN (SELECT iduser2 FROM table2 WHERE iduser1 = @userID)))

table1: 
    iduser FK

table2:
    iduser1 FK
    iduser2 FK

Мне сказали, что вложенные запросы в MySQL имеют плохую репутацию, когда дело доходит до производительности, и я уверен, что мог бы, вероятно, каким-то образом выполнить этот же запрос с помощью JOINS, но я просто не могу понять это, тем более что есть оператор OR, потому что table1. iduser может быть либо в table2.iduser1, либо в table2.iduser2

Как я могу присоединиться к одному и тому же столу дважды?


person Sydney Boy    schedule 27.05.2012    source источник


Ответы (2)


Позвольте мне возразить, что MySQL плохо обрабатывает не только подзапросы, но и EXISTS, и OR тоже. Поэтому я бы предложил другой подход к проблеме.

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

set @userID = 91;

SELECT DISTINCT T1.* FROM table1 T1
LEFT JOIN (SELECT iduser1 FROM table2 WHERE iduser2 = @userID) T21 
ON (T1.iduser = T21.iduser1)
LEFT JOIN (SELECT iduser2 FROM table2 WHERE iduser1 = @userID) T22 
ON (T1.iduser = T22.iduser2)
;

Как видите, EXISTS и OR прекрасно реализованы LEFT JOIN, который ищет каждое совпадение, если оно есть, с другими пользователями во второй таблице. Очевидно, что один и тот же пользователь в table1 может найти несколько совпадений, поэтому DISTINCT может помочь и удалить дубликаты.

Я предлагаю вам использовать JOIN везде, где вы можете, чтобы использовать MySQL.

person Community    schedule 28.05.2012
comment
Не увековечивайте миф о том, что СУЩЕСТВУЕТ медленно. Прочтите объяснениеextended.com/2010/05/27/ На самом деле все наоборот, LEFT JOIN не замыкается, в отличие от EXISTS, при первом обнаружении того, что что-то не совпадает, это не так ' Больше не нужно сканировать другие строки. Google (или любая поисковая система в этом отношении) отдает предпочтение очень старым статьям / сообщениям по заданной теме, и потребуется некоторое время, прежде чем новые открытия попадут в топ поисковых систем. Сказав это, я хотел бы, чтобы все разработчики знали о manageextended.com - person Michael Buen; 28.05.2012
comment
Это верно для Oracle DB, чей EXISTS идеален, но MySQL не так хорош. - person Dimitri; 13.06.2012

person    schedule
comment
Отлично - именно то, что мне нужно. - person Sydney Boy; 27.05.2012
comment
Отличный ответ @Michael Buen. Это дает мне идею решить мою проблему, хотя этот ответ не соответствует моему запросу. +1 - person OO7; 26.07.2015