运行封装在另一个中的查询的最有效方法是什么?
1。在查询中查询:
select
id_user
from table1
where
foo in (select foo from table2 where dt_signin > '2014-01-01 00:00')
2。使用临时表:
create table tmp_table as
select
foo
from table2
where
dt_signin > '2014-01-01 00:00'
然后查询临时表
select
id_user
from table1 t1
join tmp_table tmp
on t1.foo = tmp.foo
使用method 1
是where clause
运行中的查询(表1的#行)次或仅一次并存储在内存中以便与foo进行进一步比较?
答案 0 :(得分:1)
exists
版本经常优于其他版本
select id_user
from table1
where exists (
select 1
from table2
where
dt_signin > '2014-01-01 00:00'
and
table1.foo = foo
)
请注意,外部table1.foo
与子查询中的foo
进行比较
答案 1 :(得分:1)
你的两个问题不会做同样的事情。要使第二种方法等效,您需要select distinct
:
select distinct id_user
from table1 t1 join
tmp_table tmp
on t1.foo = tmp.foo;
由于这项额外的操作,我可能希望in
表现更好。但是,通常情况下,当您遇到特定的性能问题时,应该根据系统上的数据对其进行测试。
至于你在问题中的疑问,有很多不同的方法可以解决这个问题。以下是一些:
in
join
和distinct
in
exists
exists
join
in
exists
在理想的世界中,无论查询的表达方式如何,SQL编译器都会简单地研究查询并获得最佳的执行计划。那个世界不是我们生活的世界,唉。
临时表有时很有用(我更喜欢单一查询解决方案)的一个原因是出于优化目的:
你的子查询不是很复杂,所以这些可能不是问题。
在不同的情况下,不同的方法可能会更好。默认情况下,我会在tmp_Table(dt_signin, foo)
上构建索引并使用exists
。
答案 2 :(得分:0)
怎么样:
select
id_user
from
table1 t1
join (
select foo from table2 where dt_signin > '2014-01-01 00:00'
) t2 ONt1.foo = t2.foo
如果可以使用连接,则无需创建临时表。