There was a serious performance regression in OUTER JOIN planning
going from 8.2.4 to 8.2.5. I know Tom came up with some patches to
mitigate the issues in 8.2.5, but my testing shows that problems
remain in 8.3beta4.
The query:
SELECT
"CH"."caseNo",
"CH"."countyNo",
"CH"."chargeNo",
"CH"."statuteCite",
"CH"."sevClsCode",
"CH"."modSevClsCode",
"S"."descr" AS "sevClsCodeDescr",
"M"."descr" AS "modSevClsCodeDescr",
"CH"."descr",
"CH"."offenseDate",
"CH"."pleaCode",
"PC"."descr" AS "pleaCodeDescr",
"CH"."pleaDate",
"CH"."chargeSeqNo",
"CHST"."eventDate" AS "reopEventDate",
"CTHE"."descr" AS "reopEventDescr"
FROM "Charge" "CH"
LEFT OUTER JOIN "SevClsCode" "S" ON ("S"."sevClsCode" = "CH"."sevClsCode")
LEFT OUTER JOIN "SevClsCode" "M" ON ("M"."sevClsCode" = "CH"."modSevClsCode")
LEFT OUTER JOIN "PleaCode" "PC" ON ("PC"."pleaCode" = "CH"."pleaCode")
LEFT OUTER JOIN "CaseHist" "CHST"
ON ( "CHST"."countyNo" = "CH"."countyNo"
AND "CHST"."caseNo" = "CH"."caseNo"
AND "CHST"."histSeqNo" = "CH"."reopHistSeqNo"
)
LEFT OUTER JOIN "CaseTypeHistEvent" "CTHE"
ON ( "CHST"."eventType" = "CTHE"."eventType"
AND "CHST"."caseType" = "CTHE"."caseType"
AND "CHST"."countyNo" = "CTHE"."countyNo"
)
WHERE "CH"."caseNo" = '2007CM003476'
AND "CH"."countyNo" = 53
ORDER BY
"chargeNo",
"chargeSeqNo"
;
The attached EXPLAIN ANALYZE results show:
(1) A run of the above under 8.3beta4.
(2) A run of the above under 8.2.4.
(3) A run of the above with all OUTER JOINs changed to INNER under 8.3beta4.
-Kevin
Sort (cost=101161.84..101161.85 rows=4 width=226) (actual
time=113110.725..113110.731 rows=4 loops=1)
Sort Key: "CH"."chargeNo", "CH"."chargeSeqNo"
Sort Method: quicksort Memory: 18kB
-> Hash Left Join (cost=82004.90..101161.80 rows=4 width=226) (actual
time=110701.127..113110.637 rows=4 loops=1)
Hash Cond: (("CH"."sevClsCode")::bpchar = ("S"."sevClsCode")::bpchar)
-> Hash Left Join (cost=82003.36..101160.20 rows=4 width=195)
(actual time=110701.005..113110.503 rows=4 loops=1)
Hash Cond: (("CH"."modSevClsCode")::bpchar =
("M"."sevClsCode")::bpchar)
-> Hash Left Join (cost=82001.82..101158.64 rows=4 width=164)
(actual time=110700.858..113110.345 rows=4 loops=1)
Hash Cond: (("CH"."pleaCode")::bpchar =
("PC"."pleaCode")::bpchar)
-> Hash Left Join (cost=82000.60..101157.37 rows=4
width=128) (actual time=110700.720..113110.191 rows=4 loops=1)
Hash Cond: ((("CHST"."eventType")::bpchar =
("CTHE"."eventType")::bpchar) AND (("CHST"."caseType")::bpchar =
("CTHE"."caseType")::bpchar) AND (("CHST"."countyNo")::smallint =
("CTHE"."countyNo")::smallint))
-> Nested Loop Left Join (cost=0.00..87.70 rows=4
width=107) (actual time=0.189..0.241 rows=4 loops=1)
-> Index Scan using "Charge_pkey" on "Charge"
"CH" (cost=0.00..10.32 rows=4 width=94) (actual time=0.174..0.186 rows=4
loops=1)
Index Cond: ((("countyNo")::smallint =
53) AND (("caseNo")::bpchar = '2007CM003476'::bpchar))
-> Index Scan using "CaseHist_pkey" on
"CaseHist" "CHST" (cost=0.00..19.32 rows=2 width=32) (actual time=0.002..0.002
rows=0 loops=4)
Index Cond:
((("CHST"."countyNo")::smallint = 53) AND (("CHST"."caseNo")::bpchar =
'2007CM003476'::bpchar) AND (("CHST"."histSeqNo")::smallint =
("CH"."reopHistSeqNo")::smallint))
-> Hash (cost=44597.18..44597.18 rows=1146024
width=98) (actual time=110700.290..110700.290 rows=1146024 loops=1)
-> Subquery Scan "CTHE"
(cost=148.78..44597.18 rows=1146024 width=98) (actual time=14.673..92707.265
rows=1146024 loops=1)
-> Merge Left Join
(cost=148.78..33136.94 rows=1146024 width=77) (actual time=14.668..72106.330
rows=1146024 loops=1)
Merge Cond:
(((b."caseType")::bpchar = (d."caseType")::bpchar) AND ((b."eventType")::bpchar
= (d."eventType")::bpchar))
Join Filter:
((d."countyNo")::smallint = (c."countyNo")::smallint)
-> Nested Loop
(cost=2.79..23557.55 rows=1146024 width=67) (actual time=0.114..32623.571
rows=1146024 loops=1)
-> Index Scan using
"CaseTypeHistEventB_pkey" on "CaseTypeHistEventB" b (cost=0.00..634.28
rows=15917 width=65) (actual time=0.071..2405.293 rows=15917 loops=1)
-> Materialize
(cost=2.79..3.51 rows=72 width=2) (actual time=0.002..0.516 rows=72 loops=15917)
-> Seq Scan on
"ControlRecord" c (cost=0.00..2.72 rows=72 width=2) (actual time=0.031..0.183
rows=72 loops=1)
-> Sort (cost=145.99..151.14
rows=2060 width=15) (actual time=14.530..207.873 rows=148249 loops=1)
Sort Key: d."caseType",
d."eventType"
Sort Method: quicksort
Memory: 145kB
-> Seq Scan on
"CaseTypeHistEventD" d (cost=0.00..32.60 rows=2060 width=15) (actual
time=0.039..3.364 rows=2060 loops=1)
-> Hash (cost=1.10..1.10 rows=10 width=41) (actual
time=0.061..0.061 rows=10 loops=1)
-> Seq Scan on "PleaCode" "PC" (cost=0.00..1.10
rows=10 width=41) (actual time=0.023..0.037 rows=10 loops=1)
-> Hash (cost=1.24..1.24 rows=24 width=34) (actual
time=0.106..0.106 rows=24 loops=1)
-> Seq Scan on "SevClsCode" "M" (cost=0.00..1.24 rows=24
width=34) (actual time=0.024..0.057 rows=24 loops=1)
-> Hash (cost=1.24..1.24 rows=24 width=34) (actual time=0.087..0.087
rows=24 loops=1)
-> Seq Scan on "SevClsCode" "S" (cost=0.00..1.24 rows=24
width=34) (actual time=0.006..0.039 rows=24 loops=1)
Total runtime: 113114.552 ms
Sort (cost=2533.51..2533.53 rows=5 width=253) (actual time=435.412..435.416
rows=4 loops=1)
Sort Key: "CH"."chargeNo", "CH"."chargeSeqNo"
-> Hash Left Join (cost=2390.88..2533.46 rows=5 width=253) (actual
time=435.254..435.327 rows=4 loops=1)
Hash Cond: (("CH"."sevClsCode")::bpchar = ("S"."sevClsCode")::bpchar)
-> Hash Left Join (cost=2389.34..2531.85 rows=5 width=219) (actual
time=435.146..435.209 rows=4 loops=1)
Hash Cond: (("CH"."modSevClsCode")::bpchar =
("M"."sevClsCode")::bpchar)
-> Hash Left Join (cost=2387.80..2530.28 rows=5 width=185)
(actual time=428.365..428.420 rows=4 loops=1)
Hash Cond: (("CH"."pleaCode")::bpchar =
("PC"."pleaCode")::bpchar)
-> Hash Left Join (cost=2386.57..2529.00 rows=5
width=146) (actual time=421.921..421.967 rows=4 loops=1)
Hash Cond: ((("CHST"."eventType")::bpchar =
("CTHE"."eventType")::bpchar) AND (("CHST"."caseType")::bpchar =
("CTHE"."caseType")::bpchar))
-> Nested Loop Left Join (cost=0.00..122.50 rows=5
width=131) (actual time=4.777..4.814 rows=4 loops=1)
-> Index Scan using "Charge_pkey" on "Charge"
"CH" (cost=0.00..12.17 rows=5 width=112) (actual time=4.765..4.775 rows=4
loops=1)
Index Cond: ((("countyNo")::smallint =
53) AND (("caseNo")::bpchar = '2007CM003476'::bpchar))
-> Index Scan using "CaseHist_pkey" on
"CaseHist" "CHST" (cost=0.00..22.04 rows=2 width=41) (actual time=0.002..0.002
rows=0 loops=4)
Index Cond:
((("CHST"."countyNo")::smallint = 53) AND (("CHST"."caseNo")::bpchar =
'2007CM003476'::bpchar) AND (("CHST"."histSeqNo")::smallint =
("CH"."reopHistSeqNo")::smallint))
-> Hash (cost=2147.82..2147.82 rows=15917
width=98) (actual time=417.096..417.096 rows=15917 loops=1)
-> Subquery Scan "CTHE"
(cost=1684.48..2147.82 rows=15917 width=98) (actual time=293.804..388.572
rows=15917 loops=1)
-> Merge Right Join
(cost=1684.48..1988.65 rows=15917 width=89) (actual time=293.801..358.342
rows=15917 loops=1)
Merge Cond:
(((d."countyNo")::smallint = "inner"."?column9?") AND ((d."caseType")::bpchar =
"inner"."?column10?") AND ((d."eventType")::bpchar = "inner"."?column11?"))
-> Index Scan using
"CaseTypeHistEventD_pkey" on "CaseTypeHistEventD" d (cost=0.00..89.64
rows=2066 width=21) (actual time=9.970..36.191 rows=1460 loops=1)
-> Sort (cost=1684.48..1724.27
rows=15917 width=76) (actual time=255.997..271.497 rows=15917 loops=1)
Sort Key:
(c."countyNo")::smallint, (b."caseType")::bpchar, (b."eventType")::bpchar
-> Nested Loop
(cost=0.00..573.61 rows=15917 width=76) (actual time=9.941..88.116 rows=15917
loops=1)
-> Index Scan using
"ControlRecord_pkey" on "ControlRecord" c (cost=0.00..4.27 rows=1 width=2)
(actual time=0.062..0.069 rows=1 loops=1)
Index Cond:
(("countyNo")::smallint = 53)
-> Seq Scan on
"CaseTypeHistEventB" b (cost=0.00..410.17 rows=15917 width=74) (actual
time=9.871..45.731 rows=15917 loops=1)
-> Hash (cost=1.10..1.10 rows=10 width=47) (actual
time=6.413..6.413 rows=10 loops=1)
-> Seq Scan on "PleaCode" "PC" (cost=0.00..1.10
rows=10 width=47) (actual time=6.383..6.394 rows=10 loops=1)
-> Hash (cost=1.24..1.24 rows=24 width=40) (actual
time=6.747..6.747 rows=24 loops=1)
-> Seq Scan on "SevClsCode" "M" (cost=0.00..1.24 rows=24
width=40) (actual time=6.652..6.678 rows=24 loops=1)
-> Hash (cost=1.24..1.24 rows=24 width=40) (actual time=0.081..0.081
rows=24 loops=1)
-> Seq Scan on "SevClsCode" "S" (cost=0.00..1.24 rows=24
width=40) (actual time=0.004..0.030 rows=24 loops=1)
Total runtime: 444.599 ms
Sort (cost=44.56..44.57 rows=1 width=245) (actual time=0.196..0.196 rows=0
loops=1)
Sort Key: "CH"."chargeNo", "CH"."chargeSeqNo"
Sort Method: quicksort Memory: 17kB
-> Nested Loop Left Join (cost=1.54..44.55 rows=1 width=245) (actual
time=0.182..0.182 rows=0 loops=1)
-> Nested Loop (cost=1.54..40.26 rows=1 width=256) (actual
time=0.180..0.180 rows=0 loops=1)
-> Nested Loop (cost=1.54..37.35 rows=1 width=256) (actual
time=0.178..0.178 rows=0 loops=1)
Join Filter: (("CH"."sevClsCode")::bpchar =
("S"."sevClsCode")::bpchar)
-> Nested Loop (cost=1.54..35.81 rows=1 width=225)
(actual time=0.175..0.175 rows=0 loops=1)
Join Filter: (("CH"."pleaCode")::bpchar =
("PC"."pleaCode")::bpchar)
-> Nested Loop (cost=1.54..34.59 rows=1 width=189)
(actual time=0.172..0.172 rows=0 loops=1)
-> Nested Loop (cost=1.54..31.23 rows=1
width=138) (actual time=0.170..0.170 rows=0 loops=1)
-> Hash Join (cost=1.54..11.88 rows=1
width=125) (actual time=0.168..0.168 rows=0 loops=1)
Hash Cond:
(("CH"."modSevClsCode")::bpchar = ("M"."sevClsCode")::bpchar)
-> Index Scan using "Charge_pkey"
on "Charge" "CH" (cost=0.00..10.32 rows=4 width=94) (actual time=0.042..0.050
rows=4 loops=1)
Index Cond:
((("countyNo")::smallint = 53) AND (("caseNo")::bpchar =
'2007CM003476'::bpchar))
-> Hash (cost=1.24..1.24 rows=24
width=34) (actual time=0.096..0.096 rows=24 loops=1)
-> Seq Scan on "SevClsCode"
"M" (cost=0.00..1.24 rows=24 width=34) (actual time=0.011..0.044 rows=24
loops=1)
-> Index Scan using "CaseHist_pkey" on
"CaseHist" "CHST" (cost=0.00..19.32 rows=2 width=32) (never executed)
Index Cond:
((("CHST"."countyNo")::smallint = 53) AND (("CHST"."caseNo")::bpchar =
'2007CM003476'::bpchar) AND (("CHST"."histSeqNo")::smallint =
("CH"."reopHistSeqNo")::smallint))
-> Index Scan using "CaseTypeHistEventB_pkey"
on "CaseTypeHistEventB" b (cost=0.00..3.34 rows=1 width=60) (never executed)
Index Cond: (((b."caseType")::bpchar =
("CHST"."caseType")::bpchar) AND ((b."eventType")::bpchar =
("CHST"."eventType")::bpchar))
-> Seq Scan on "PleaCode" "PC" (cost=0.00..1.10
rows=10 width=41) (never executed)
-> Seq Scan on "SevClsCode" "S" (cost=0.00..1.24 rows=24
width=34) (never executed)
-> Seq Scan on "ControlRecord" c (cost=0.00..2.90 rows=1
width=2) (never executed)
Filter: ((c."countyNo")::smallint = 53)
-> Index Scan using "CaseTypeHistEventD_pkey" on "CaseTypeHistEventD"
d (cost=0.00..4.27 rows=1 width=11) (never executed)
Index Cond: (((d."countyNo")::smallint =
(c."countyNo")::smallint) AND ((d."caseType")::bpchar = (b."caseType")::bpchar)
AND ((d."eventType")::bpchar = (b."eventType")::bpchar))
Total runtime: 0.747 ms
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?
http://archives.postgresql.org