我需要根据一个表(tableA)的选择结果从表列表(list1,list2,list3,...)中进行选择。如何重用该表中的选择结果(tableA)?
我的解决方案是
select * from list1 where list1.id in(select id from tableA where ...)
select * from list2 where list2.id in(select id from tableA where ...)
select * from list3 where list3.id in(select id from tableA where ...)
...
在我的解决方案中,从tableA中选择id,其中...... 执行3次,可能需要很长时间,效率不高。 在我的想象中,从tableA中选择id,其中...... 应该只执行一次。
任何人都可以帮助我吗?
答案 0 :(得分:2)
有两点需要注意。首先,在某些版本的MySQL中,exists
版本效率更高:
select *
from list1
where exists (select 1 from tableA a where a.id = list1.id and (...))
. . .
其次,您希望在tableA
上拥有正确的索引来优化查询。基本上,正确的索引是一个复合索引,第一个键是id
,where
子句中的列跟随。
在索引中排序列的最佳方法取决于where
条件。如果条件是由and
连接的所有相等条件,则排序无关紧要。
答案 1 :(得分:1)
您可以使用临时表将子查询的结果存储在内存中,并使用简单的IN (select id from tmptable)
替换子查询。我假设您的原始子查询稍微复杂一些,可能包含复杂的WHERE
条件:
CREATE TEMPORARY TABLE tmptable
AS SELECT id FROM tableA WHERE complex = condition AND more = conditions;
SELECT * FROM list1 l WHERE l.id IN (SELECT id FROM tmptable)
SELECT * FROM list2 l WHERE l.id IN (SELECT id FROM tmptable)
...
因此,复杂查询只执行一次,结果存储在内存中,并被以下查询重用。
答案 2 :(得分:0)
如果所有3个SELECT都返回兼容的结果,您可以尝试使用UNION ALL组合它们:
select *
FROM
(
select * from list1
UNION ALL
select * from list2
UNION ALL
select * from list3
) as dt
where id in (select id from tableA where ...)
但我怀疑MySQL的优化器可以很好地解决这个问题......
答案 3 :(得分:-1)
没有更有效的方法来做到这一点。没有解决这个基本事实,你必须将两个列表相互比较n次,其中n是你拥有的列表表的数量。
这有点类似于以下一组补充:
a + 5 = ?
b + 5 = ?
c + 5 = ?
d + 5 = ?
嘿,有没有办法优化这个?毕竟我每次只加5!
不,不是真的。在这个例子中,您可以编写一个函数,该函数将5添加到某个东西,这将减少代码量,并且从DRY角度来看更好。但是,这不会在减少执行时间方面“优化”它。