Folks,
I have a following query that used to work as intended on 8.3.5 :
SELECT COUNT(*)
FROM jiveDeployRequest dr
LEFT JOIN jiveDeployType dt ON dr.deployTypeId = dt.deployTypeId
LEFT JOIN jiveDeployStatus ds ON dr.deployStatusId = ds.deployStatusId
LEFT OUTER JOIN jiveCustomerInstallationDeploy cid ON dr.deployRequestId =
cid.deployRequestId
LEFT JOIN jiveCustomerInstallation ci ON cid.customerInstallationId =
ci.customerInstallationId
LEFT JOIN jiveInstallationType it ON ci.installationTypeId=it.installationTypeId
LEFT OUTER JOIN jiveCloudUser cu ON dr.cloudUserId = cu.cloudUserId
WHERE cid.customerInstallationId = 660
AND
(SELECT CASE WHEN ds.statusCode <> 'inprocess'
OR now()-lastStatusUpdate < interval '00:10:00' THEN statusCode ELSE
'unknown' END) = 'inprocess'
AND dt.typeCode != 'disable-magic-admin'
The plan was as follows :
1. Aggregate (cost=1178.30..1178.31 rows=1 width=0)
2. -> Nested Loop (cost=6.19..1178.29 rows=1 width=0)
3. -> Nested Loop Left Join (cost=6.19..1178.01 rows=1 width=8)
4. Join Filter: (ci.installationtypeid = it.installationtypeid)
5. -> Nested Loop Left Join (cost=6.19..1176.61 rows=1
width=16)
6. -> Nested Loop Left Join (cost=6.19..1168.25 rows=1
width=16)
7. -> Hash Left Join (cost=6.19..1167.97 rows=1
width=24)
8. Hash Cond: (dr.deploystatusid =
ds.deploystatusid)
9. Filter: (((subplan))::text =
'inprocess'::text)
10. -> Nested Loop (cost=5.08..1163.12
rows=103 width=40)
11. -> Bitmap Heap Scan on
jivecustomerinstallationdeploy cid (cost=5.08..315.56 rows=103 width=16)
12. Recheck Cond:
(customerinstallationid = 660)
13. -> Bitmap Index Scan on
jcid_customerinstallationid (cost=0.00..5.05 rows=103 width=0)
14. Index Cond:
(customerinstallationid = 660)
15. -> Index Scan using
jivedeployrequest_pk on jivedeployrequest dr (cost=0.00..8.22 rows=1 width=40)
16. Index Cond:
(dr.deployrequestid = cid.deployrequestid)
17. -> Hash (cost=1.05..1.05 rows=5
width=16)
18. -> Seq Scan on jivedeploystatus ds
(cost=0.00..1.05 rows=5 width=16)
19. SubPlan
20. -> Result (cost=0.00..0.02 rows=1
width=0)
21. -> Index Scan using jiveclouduser_pk on
jiveclouduser cu (cost=0.00..0.27 rows=1 width=8)
22. Index Cond: (dr.clouduserid =
cu.clouduserid)
23. -> Index Scan using jivecustomerinstallation_pk on
jivecustomerinstallation ci (cost=0.00..8.34 rows=1 width=16)
24. Index Cond: ((ci.customerinstallationid = 660)
AND (cid.customerinstallationid = ci.customerinstallationid))
25. -> Seq Scan on jiveinstallationtype it (cost=0.00..1.18
rows=18 width=8)
26. -> Index Scan using jivedeploytype_pk on jivedeploytype dt
(cost=0.00..0.27 rows=1 width=8)
27. Index Cond: (dt.deploytypeid = dr.deploytypeid)
28. Filter: ((dt.typecode)::text <> 'disable-magic-admin'::text)
After upgrade to 9.2 the query doesn't return the same results any more, and
the execution plan has changed :
1. Aggregate (cost=17.15..17.16 rows=1 width=0)
2. -> Nested Loop Left Join (cost=0.00..17.15 rows=1 width=0)
3. -> Nested Loop (cost=0.00..16.85 rows=1 width=16)
4. -> Nested Loop (cost=0.00..16.56 rows=1 width=24)
5. -> Index Scan using jcid_customerinstallationid on
jivecustomerinstallationdeploy cid (cost=0.00..8.27 rows=1 width=16)
6. Index Cond: (customerinstallationid = 660)
7. -> Index Scan using jivedeployrequest_pk on
jivedeployrequest dr (cost=0.00..8.28 rows=1 width=40)
8. Index Cond: (deployrequestid =
cid.deployrequestid)
9. -> Index Scan using jivedeploytype_pk on jivedeploytype
dt (cost=0.00..0.27 rows=1 width=8)
10. Index Cond: (deploytypeid = dr.deploytypeid)
11. Filter: ((typecode)::text <>
'disable-magic-admin'::text)
12. -> Index Scan using jivedeploystatus_pk on jivedeploystatus ds
(cost=0.00..0.29 rows=1 width=16)
13. Index Cond: (dr.deploystatusid = deploystatusid)
14. Filter: (((SubPlan 1))::text = 'inprocess'::text)
15. SubPlan 1
16. -> Result (cost=0.00..0.02 rows=1 width=0)
Somehow the subquery with CASE in WHERE clause is affecting the LEFT JOIN, and
that causes the query to return extra rows.