Ins*_*ous 28 sql postgresql performance query-optimization
说我有一个表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
Run Code Online (Sandbox Code Playgroud)
clientid是一个回到client桌面的外键itemid是一个回到item表的外键type只是B或Samount 是一个整数和一张桌子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
Run Code Online (Sandbox Code Playgroud)
我需要把所有从行order,对于相同的clientid同一date具有相反的type值.请记住type,只能有两个值之一 - B或S.在上面的例子中,这将是行23和24.
另一个约束是相应的行processed必须是truefor orderid.
我的查询到目前为止
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
Run Code Online (Sandbox Code Playgroud)
问题:保持processed = truejoin子句的一部分会降低查询速度.如果我将它移动到WHERE子句,那么性能会好得多.这引起了我的兴趣,我想知道为什么.
而值列(主键和相应的外键列被索引value,processed等等)则不是.
免责声明:我继承了这种DB结构,性能差异大约为6秒.
您看到差异的原因是由于计划程序正在组合的执行计划,这显然根据查询而不同(可以说,它应该优化2个查询是相同的,这可能是一个错误).这意味着规划人员认为必须以特定方式工作才能获得每个语句中的结果.
当您在JOIN中执行此操作时,计划程序可能必须从表中进行选择,按"True"部分进行筛选,然后加入结果集.我想这是一个大表,因此要查看大量数据,并且它不能有效地使用索引.
我怀疑如果你在WHERE子句中这样做,规划者就会选择一种效率更高的路由(即基于索引或预过滤的数据集).
您可以通过在两列上添加索引来快速(如果不是更快)使连接工作(不确定Postgres是否支持包含列和多列索引).
简而言之,规划者就是选择2条不同的路径来获取结果集的问题,其中一条路线的效率不如另一条路线.如果没有完整的表格信息和EXPLAIN ANALYZE信息,我们就不可能知道原因是什么.
如果您需要有关特定查询执行此操作的详细信息,则需要提供更多信息.然而原因是计划者选择不同的路线.
附加阅读材料:
http://www.postgresql.org/docs/current/static/explicit-joins.html
只是略读,似乎postgres规划师没有重新订购连接来优化它.尝试更改语句中连接的顺序,看看你是否获得相同的性能......只是一个想法.
| 归档时间: |
|
| 查看次数: |
32003 次 |
| 最近记录: |