假设我有一张order号的桌子

id | clientid | type | amount | itemid | date
---|----------|------|--------|--------|-----------
23 | 258      | B    | 150    | 14     | 2012-04-03
24 | 258      | S    | 69     | 14     | 2012-04-03
25 | 301      | S    | 10     | 20     | 2012-04-03
26 | 327      | B    | 54     | 156    | 2012-04-04
  • clientid是返回client表的外键
  • itemid是返回item表的外键
  • type只是BS
  • amount是一个整数

还有一张processed号桌

id | orderid | processed | date
---|---------|-----------|---------
41 | 23      | true      | 2012-04-03
42 | 24      | true      | 2012-04-03
43 | 25      | false     | <NULL>
44 | 26      | true      | 2012-04-05     

我需要得到order的所有行,对于相同的clientid,在相同的date上有相反的type值.记住type只能有两个值中的一个——BS.在上面的示例中,这将是第23行和第24行.

另一个约束是,对于orderidprocessed中对应的行必须是true.

到目前为止我的问题

SELECT c1.clientid,
       c1.date,
       c1.type,
       c1.itemid,
       c1.amount,
       c2.date,
       c2.type,
       c2.itemid,
       c2.amount

FROM   order c1
INNER JOIN order c2 ON c1.itemid    =  c2.itemid AND
                       c1.date      =  c2.date   AND
                       c1.clientid  =  c2.clientid AND
                       c1.type     <>  c2.type AND
                       c1.id        <  c2.id

INNER JOIN processed p1 ON p1.orderid   =  c1.id AND
                         p1.processed =  true
INNER JOIN processed p2 ON p2.orderid   =  c2.id AND
                         p2.processed =  true

QUESTION:processed = true保留为join子句的一部分会减慢查询速度.如果我把它移到WHERE子句,那么性能会更好.这引起了我的兴趣和兴趣.

主键和相应的外键列被索引,而值列(valueprocessed等)没有索引.

Disclaimer: I have inherited this DB structure and the performance difference is roughly 6 seconds.

推荐答案

您看到差异的原因是由于计划员正在制定的执行计划,这显然是不同的,取决于查询(可以说,它应该优化两个查询以使其相同,这可能是一个错误).这意味着规划者认为它必须以特定的方式工作,才能在每个声明中得到结果.

在联接中执行此操作时,计划者可能需要从表中进行 Select ,按"True"部分进行筛选,然后联接结果集.我认为这是一个很大的表,因此需要查看大量数据,而且它不能有效地使用索引.

我怀疑如果你在WHERE子句中这样做,规划者会 Select 一条更有效的路由(即基于索引的路由,或预过滤的数据集).

通过在两列上添加索引(不确定Postgres是否支持包含的列和多列索引),您可能可以使联接工作得同样快(如果不是更快的话).

简言之,规划者的问题在于 Select 两条不同的路由到达结果集,其中一条没有另一条有效.如果没有完整的表格信息和解释分析信息,我们不可能知道原因是什么.

如果您想了解特定查询执行此操作的具体原因,需要提供更多信息.然而,原因是规划者 Select 了不同的路由.

Additional Reading Material:

http://www.postgresql.org/docs/current/static/explicit-joins.html

只是略读了一下,似乎博士后的规划师没有重新安排加入以优化它.try 更改语句中连接的顺序,看看是否能获得相同的性能...只是一个 idea .

Postgresql相关问答推荐

如何在Windows中安装sql for golang

在postgres中查找多个表中不同列的计数和总和

哪种数据类型是除法的结果?

Postgres-pgloader-默认情况下,在PostgreSQL中将列名转换为小写

如何在 postgres 中查询键设置为空值的 jsonb 字段

如何在postgresql中按时间查询

EF Core添加迁移目标postgreeSQL返回无法加载类型'Microsoft.EntityFrameworkCore.Storage.IRelationalValueBufferFactoryFactory

PostgreSQL unnest 与空数组

在 Postgresql 中获取星期几

postgresql 在查询中插入空值

使用 postgres regexp_replace 将字符串列表替换为始终相同的字符串

在远程机器上Restore dump

将 SELECT 结果作为参数传递给 postgreSQL 函数

使用 current_setting() 判断值

适配器 Ecto.Adapters.Postgres 未编译

安装时 postgres 的默认用户

错误:ERROR: table name specified more than once

PostgreSQL 条件 where 子句

PostgreSQL:如果不存在则创建表 AS

判断 PostgreSQL 中的角色是否设置了密码