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;