Sql 运行封装查询的最有效方法
运行封装在另一个数据库中的查询最有效的方法是什么 一,。在查询内查询: 二,。通过使用临时表: 然后查询临时表 使用Sql 运行封装查询的最有效方法,sql,performance,postgresql,Sql,Performance,Postgresql,运行封装在另一个数据库中的查询最有效的方法是什么 一,。在查询内查询: 二,。通过使用临时表: 然后查询临时表 使用方法1是where子句中的查询运行(#表1的行)次还是仅运行一次,并存储在内存中,以便与foo进行进一步比较?关于: select id_user from table1 t1 join ( select foo from table2 where dt_signin > '2014-01-01 00:00' ) t2 ONt1.foo = t2.
方法1
是where子句中的查询运行(#表1的行)次还是仅运行一次,并存储在内存中,以便与foo进行进一步比较?关于:
select
id_user
from
table1 t1
join (
select foo from table2 where dt_signin > '2014-01-01 00:00'
) t2 ONt1.foo = t2.foo
如果可以使用联接,则无需创建临时表。存在的变量通常优于其他变量
select id_user
from table1
where exists (
select 1
from table2
where
dt_signin > '2014-01-01 00:00'
and
table1.foo = foo
)
请注意,外部表1.foo
与子查询中的foo
进行比较您的两个查询做的事情并不相同。要使第二种方法等效,您需要选择distinct
:
select distinct id_user
from table1 t1 join
tmp_table tmp
on t1.foo = tmp.foo;
由于这个额外的操作,我可能期望
中的执行得更好。但是,一般来说,当您有一个特定的性能问题时,您应该在系统上的数据上测试它
至于你在这个问题上的疑问,有很多不同的方法来解决。以下是一些:
- 在
两个表具有连接
和不同
两个表中有,
存在两个具有
存在具有的子查询
存在两个带有的表
带有连接的CTE
带的CTE在
存在带有的CTE
在理想情况下,SQL编译器只需研究查询并获得最佳执行计划,而不管查询是如何表达的。唉,那个世界不是我们生活的世界
临时表有时很有用(我更喜欢单查询解决方案)的一个原因是出于优化目的:
临时表的统计信息是已知的,因此优化器可以选择更好的计划
可以在临时表上构建索引以提高性能
您的子查询不是很复杂,因此这些可能不是问题
在不同的情况下,不同的方法可能效果更好。默认情况下,我会在tmp_表(dt_sign,foo)
上建立一个索引,并使用exists
有一个where exists
子句可能会帮助您。还可以看到,具有两个查询的解决方案通常比单个查询慢,尤其是在第一个查询读取和写入数据的情况下。具有in的子查询是否需要对第一个表的每一行执行该子查询?(参考问题中的方法1)@Thiago。我不知道Postgres是否总是按顺序执行这些查询。有些数据库可以。其他人则通过子查询对
中的进行了优化。针对特定情况的真正答案是使用explain
。
select
id_user
from
table1 t1
join (
select foo from table2 where dt_signin > '2014-01-01 00:00'
) t2 ONt1.foo = t2.foo
select id_user
from table1
where exists (
select 1
from table2
where
dt_signin > '2014-01-01 00:00'
and
table1.foo = foo
)
select distinct id_user
from table1 t1 join
tmp_table tmp
on t1.foo = tmp.foo;