この式を考えると:
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)))
EXISTS を使用すると、その 2 つのサブクエリを次のように減らすことができます。
set @userID = 91;
SELECT * FROM table1 x
WHERE EXISTS(
select * from table2 z
where (z.user2 = @userID and iduser1 = x.iduser)
OR (z.user1 = @userID and iduser2 = x.iduser)
)
OR はクエリの速度を低下させる可能性がありますが、RDBMS では必ずしも短絡するとは限りません。その場合は、CASE WHEN を使用して短絡を試みる必要があります。OR を使用すると実行に 5 秒かかるクエリがありましたが、CASE WHEN に変換すると 0 秒未満でした:
set @userID = 91;
SELECT * FROM table1 x
WHERE EXISTS(
select * from table2 z
where
CASE WHEN z.user2 = @userID THEN
IF(z.iduser1 = x.iduser, 1, 0)
CASE WHEN z.user1 = @userID THEN
IF(z.iduser2 = x.iduser, 1, 0)
END = 1
)
ブール式は自動的に整数 (0(false) または 1(true)) にキャストされるため、次のようにすることもできます。
set @userID = 91;
SELECT * FROM table1 x
WHERE EXISTS(
select * from table2 z
where
CASE WHEN z.user2 = @userID THEN
z.iduser1 = x.iduser
CASE WHEN z.user1 = @userID THEN
z.iduser2 = x.iduser
END = 1
)
またはこれ:
set @userID = 91;
SELECT * FROM table1 x
WHERE EXISTS(
select * from table2 z
where
CASE WHEN z.user2 = @userID THEN
z.iduser1 = x.iduser
CASE WHEN z.user1 = @userID THEN
z.iduser2 = x.iduser
END
)
MySQL を使用していない場合は、次のようにします。
set @userID = 91;
SELECT * FROM table1 x
WHERE EXISTS(
select * from table2 z
where
CASE WHEN z.user2 = @userID THEN
CASE WHEN z.iduser1 = x.iduser THEN 1 END
CASE WHEN z.user1 = @userID THEN
CASE WHEN z.iduser2 = x.iduser THEN 1 END
END = 1
)