性能上的差异:条件放置在INNER JOIN VS WHERE子句(Performance diff

2019-06-25 02:18发布

说我有一个表的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 。 在以上示例将是行2324

另一个制约因素是,在相应的行processed必须是trueorderid

我的查询到目前为止

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

问:保持processed = true为加盟条款的一部分被拖慢的查询。 如果我将它移动到WHERE子句,则表现要好得多。 这引起了我的兴趣, 我想知道这是为什么

而值列(主键和相应的外键列被索引valueprocessed等)则不是。

免责声明:我继承了这个DB结构和性能差异大约是6秒。

Answer 1:

您所看到的差异的原因是由于该计划者放在一起的执行计划,这是明显的不同,这取决于查询(可以说,应该优化2个查询是相同的,这可能是一个错误)。 这意味着,规划师认为它有一种特殊的方式来工作,得到的结果在每个语句。

当内JOIN做到这一点,计划将可能有被“真”的一部分,从该表中,过滤,选择,然后加入结果集。 我会想象这是一个大表,因此很多数据的翻阅,也不能以有效地使用索引。

我怀疑,如果你在WHERE子句中做到这一点,规划是选择更有效的路由(即要么基于索引的,或预过滤的数据集)。

你也许可以让参加工作快(如果不是更快),请通过在两列的索引(不知道是否包括列和多列索引支持的Postgres还)。

总之,规划是它是选择2条不同的路线去的结果集的问题,其中之一是没有其他高效。 这是我们不可能知道是什么原因不完整的表信息和EXPLAIN分析信息。

如果你想在你为什么特定查询是这样做的细节,你需要提供更多的信息。 然而,原因是计划者选择不同的路线。

其他阅读材料:

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

只是脱脂,似乎Postgres的策划者不会重新加入顺序进行优化。 试着改变你的声明中加入才能看到,如果你再拿到相同的性能...只是一个想法。



文章来源: Performance difference: condition placed at INNER JOIN vs WHERE clause