Since this is a large query, attachments for the explains / query. Configuration: dev_iqdb=# select version(); version ------------------------------------------------------------------------ PostgreSQL 7.4beta1 on i386-portbld-freebsd4.7, compiled by GCC 2.95.4 (1 row)
SET default_statistics_target = 1000; ANALYZE; set from_collapse_limit = 100; set join_collapse_limit = 20; The query is a segment of a report but shows the issue well enough. Effectively, the planner has amazingly inaccurate row estimates. With nestloop on, it estimates 1 row returned. With it off it estimates 12 rows returned. The query actually returns several hundred thousand entries. ANALYZE output is in the nestloopoff file. With nestloopon I actually run out of memory prior to query completion (1GB ram to the single process). Any hints? I'm basically stuck. Oh, and I would like to ask for a pgadmin feature -- visual explain :)
QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Merge Right Join (cost=62642.05..62651.25 rows=12 width=74) (actual time=682187.16..698880.37 rows=362126 loops=1) Merge Cond: ("outer".service_id = "inner".service_id) Filter: (("outer".account_id = "inner".account_id) OR ("outer".account_id IS NULL)) -> Index Scan using exposure_service_id_key on exposure tse (cost=0.00..8.27 rows=300 width=8) (actual time=0.47..18.46 rows=300 loops=1) -> Sort (cost=62642.05..62642.08 rows=12 width=74) (actual time=676920.81..683084.38 rows=813179 loops=1) Sort Key: tss.service_id -> Hash Left Join (cost=62630.22..62641.84 rows=12 width=74) (actual time=590658.20..641520.35 rows=813179 loops=1) Hash Cond: ("outer".service_order_detail_id = "inner".service_order_detail_id_new) Filter: ("inner".service_order_detail_id_new IS NULL) -> Merge Join (cost=62622.49..62626.34 rows=12 width=74) (actual time=590651.37..621488.04 rows=829688 loops=1) Merge Cond: ("outer".account_id = "inner".parent_account_id) Join Filter: ("inner".account_id = "outer".parent_account_id) -> Index Scan using account_pkey on account aa (cost=0.00..1004.01 rows=19539 width=8) (actual time=0.43..0.88 rows=11 loops=1) -> Sort (cost=62622.49..62622.89 rows=158 width=82) (actual time=577505.17..591090.69 rows=1659376 loops=1) Sort Key: ab.parent_account_id -> Hash Join (cost=61817.14..62616.72 rows=158 width=82) (actual time=459071.50..511843.21 rows=1659376 loops=1) Hash Cond: ("outer".account_id = "inner".account_id) -> Seq Scan on breakdown ab (cost=0.00..602.67 rows=39067 width=8) (actual time=4.64..493.15 rows=39067 loops=1) -> Hash (cost=61816.94..61816.94 rows=79 width=78) (actual time=459061.75..459061.75 rows=0 loops=1) -> Hash Join (cost=61803.77..61816.94 rows=79 width=78) (actual time=287563.65..450075.88 rows=829688 loops=1) Hash Cond: ("outer".service_order_detail_type_id = "inner".service_order_detail_type_id) -> Hash Join (cost=61802.74..61814.33 rows=158 width=82) (actual time=287562.87..419673.93 rows=1121988 loops=1) Hash Cond: ("outer".service_semantic_type_id = "inner".service_semantic_type_id) -> Hash Join (cost=61801.71..61810.93 rows=158 width=74) (actual time=287562.31..383292.28 rows=1121988 loops=1) Hash Cond: ("outer".service_semantic_type_id = "inner".service_semantic_type_id) -> Merge Join (cost=61800.67..61807.52 rows=158 width=66) (actual time=287561.86..349895.76 rows=1121988 loops=1) Merge Cond: ("outer".service_id = "inner".service_id) -> Sort (cost=61660.77..61661.17 rows=158 width=66) (actual time=287532.78..298241.29 rows=1121988 loops=1) Sort Key: tsb.service_id -> Hash Join (cost=60582.21..61655.00 rows=158 width=66) (actual time=166995.46..234437.41 rows=1121988 loops=1) Hash Cond: ("outer".service_order_id = "inner".service_order_id) -> Seq Scan on service_order bso (cost=0.00..908.14 rows=32614 width=16) (actual time=5.57..1434.72 rows=32614 loops=1) -> Hash (cost=60581.82..60581.82 rows=158 width=54) (actual time=166989.39..166989.39 rows=0 loops=1) -> Hash Join (cost=1230.79..60581.82 rows=158 width=54) (actual time=1262.35..151200.29 rows=1121988 loops=1) Hash Cond: ("outer".account_id = "inner".account_id) -> Hash Join (cost=1226.78..52863.43 rows=1542558 width=50) (actual time=1261.63..100418.30 rows=1573190 loops=1) Hash Cond: ("outer".subservice_id = "inner".service_id) -> Hash Join (cost=1128.58..29626.86 rows=1542558 width=42) (actual time=1075.57..43565.86 rows=1573190 loops=1) Hash Cond: ("outer".service_id = "inner".service_id) -> Seq Scan on service_order_detail bsod (cost=0.00..1973.39 rows=47739 width=30) (actual time=0.14..1600.43 rows=47739 loops=1) -> Hash (cost=1061.26..1061.26 rows=26926 width=12) (actual time=1075.06..1075.06 rows=0 loops=1) -> Seq Scan on breakdown tsb (cost=0.00..1061.26 rows=26926 width=12) (actual time=93.94..643.40 rows=26926 loops=1) -> Hash (cost=95.96..95.96 rows=896 width=12) (actual time=185.74..185.74 rows=0 loops=1) -> Seq Scan on service tss (cost=0.00..95.96 rows=896 width=12) (actual time=168.07..179.79 rows=896 loops=1) -> Hash (cost=4.01..4.01 rows=1 width=4) (actual time=0.33..0.33 rows=0 loops=1) -> Index Scan using single_null_parent_account_hack on account ap (cost=0.00..4.01 rows=1 width=4) (actual time=0.26..0.28 rows=1 loops=1) Filter: (parent_account_id IS NULL) -> Sort (cost=139.90..142.14 rows=896 width=8) (actual time=28.11..6577.04 rows=1122010 loops=1) Sort Key: ss.service_id -> Seq Scan on service ss (cost=0.00..95.96 rows=896 width=8) (actual time=8.06..20.39 rows=896 loops=1) -> Hash (cost=1.03..1.03 rows=3 width=16) (actual time=0.13..0.13 rows=0 loops=1) -> Seq Scan on semantic_type tsst (cost=0.00..1.03 rows=3 width=16) (actual time=0.03..0.07 rows=3 loops=1) -> Hash (cost=1.03..1.03 rows=3 width=16) (actual time=0.26..0.26 rows=0 loops=1) -> Seq Scan on semantic_type sst (cost=0.00..1.03 rows=3 width=16) (actual time=0.16..0.19 rows=3 loops=1) -> Hash (cost=1.02..1.02 rows=1 width=4) (actual time=0.27..0.27 rows=0 loops=1) -> Seq Scan on service_order_detail_type (cost=0.00..1.02 rows=1 width=4) (actual time=0.18..0.20 rows=1 loops=1) Filter: ((service_order_detail_type_code)::text = 'create'::text) -> Hash (cost=6.78..6.78 rows=378 width=4) (actual time=6.18..6.18 rows=0 loops=1) -> Seq Scan on service_order_service_change bsosc (cost=0.00..6.78 rows=378 width=4) (actual time=0.17..3.66 rows=378 loops=1) Total runtime: 700880.59 msec (60 rows)
QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop Left Join (cost=2488.35..2503.53 rows=1 width=74) Filter: (("inner".account_id = "outer".account_id) OR ("inner".account_id IS NULL)) -> Nested Loop Left Join (cost=2488.35..2500.91 rows=1 width=74) Join Filter: ("outer".service_order_detail_id = "inner".service_order_detail_id_new) Filter: ("inner".service_order_detail_id_new IS NULL) -> Hash Join (cost=2488.35..2489.40 rows=1 width=74) Hash Cond: ("outer".service_semantic_type_id = "inner".service_semantic_type_id) -> Seq Scan on semantic_type sst (cost=0.00..1.03 rows=3 width=16) -> Hash (cost=2488.34..2488.34 rows=1 width=66) -> Merge Join (cost=2430.84..2488.34 rows=1 width=66) Merge Cond: ("outer".account_id = "inner".account_id) Join Filter: (("outer".service_semantic_type_id = "inner".service_semantic_type_id) AND ("outer".subservice_id = "inner".service_id)) -> Nested Loop (cost=2290.94..27839.41 rows=485 width=78) Join Filter: ("inner".service_id = "outer".service_id) -> Nested Loop (cost=2290.94..6871.89 rows=15 width=74) -> Nested Loop (cost=2290.94..6866.59 rows=5 width=58) Join Filter: ("outer".service_order_detail_type_id = "inner".service_order_detail_type_id) -> Merge Join (cost=2290.94..6856.21 rows=10 width=62) Merge Cond: ("outer".account_id = "inner".parent_account_id) Join Filter: ("inner".account_id = "outer".parent_account_id) -> Nested Loop (cost=0.00..1223416.10 rows=190913 width=58) -> Nested Loop (cost=0.00..718440.38 rows=95478 width=54) -> Nested Loop (cost=0.00..335160.18 rows=95478 width=46) -> Nested Loop (cost=0.00..3472.57 rows=65228 width=20) -> Index Scan using account_pkey on account ap (cost=0.00..1004.01 rows=2 width=4) Filter: (parent_account_id IS NULL) -> Seq Scan on service_order bso (cost=0.00..908.14 rows=32614 width=16) -> Index Scan using sod_service_order_id_idx on service_order_detail bsod (cost=0.00..5.06 rows=2 width=30) Index Cond: ("outer".service_order_id = bsod.service_order_id) -> Index Scan using service_pkey on service ss (cost=0.00..4.00 rows=1 width=8) Index Cond: ("outer".service_id = ss.service_id) -> Index Scan using breakdown_pkey on breakdown ab (cost=0.00..5.26 rows=2 width=8) Index Cond: (ab.account_id = "outer".account_id) -> Sort (cost=2290.94..2339.79 rows=19539 width=8) Sort Key: aa.parent_account_id -> Seq Scan on account aa (cost=0.00..898.39 rows=19539 width=8) -> Seq Scan on service_order_detail_type (cost=0.00..1.02 rows=1 width=4) Filter: ((service_order_detail_type_code)::text = 'create'::text) -> Seq Scan on semantic_type tsst (cost=0.00..1.03 rows=3 width=16) -> Seq Scan on breakdown tsb (cost=0.00..1061.26 rows=26926 width=12) -> Sort (cost=139.90..142.14 rows=896 width=12) Sort Key: tss.account_id -> Seq Scan on service tss (cost=0.00..95.96 rows=896 width=12) -> Seq Scan on service_order_service_change bsosc (cost=0.00..6.78 rows=378 width=4) -> Index Scan using exposure_service_id_key on exposure tse (cost=0.00..2.60 rows=1 width=8) Index Cond: ("outer".service_id = tse.service_id) (46 rows)
SELECT bso.service_order_id , service_order_detail_id , bsod.service_id AS to_retail_service_id , bsod.quantity AS to_retail_service_quantity , sst.service_semantic_type_code AS to_retail_service_semantic_type_code , tss.service_id AS to_contract_service_id , tsb.quantity * bsod.quantity AS to_contract_service_quantity , tsst.service_semantic_type_code AS to_contract_service_semantic_type_code , bso.account_id AS client_account_id , bsod.account_instance_id AS client_account_instance_id , aa.account_id AS inquent_plc_account_id , bso.status_timestamp AS timestamp FROM billing.service_order AS bso JOIN billing.service_order_detail AS bsod USING (service_order_id) JOIN billing.service_order_detail_type USING (service_order_detail_type_id) JOIN service.service AS ss USING (service_id) JOIN service.semantic_type AS sst USING (service_semantic_type_id) JOIN account.breakdown AS ab ON (ab.account_id = bso.account_id) JOIN account.account AS aa ON (aa.account_id = ab.parent_account_id) JOIN account.account AS ap ON (ap.account_id = aa.parent_account_id AND ap.parent_account_id IS NULL) JOIN service.breakdown AS tsb ON (ss.service_id = tsb.service_id) JOIN service.service AS tss ON (tsb.subservice_id = tss.service_id AND tss.account_id = ap.account_id) JOIN service.semantic_type AS tsst ON (tsst.service_semantic_type_id = tss.service_semantic_type_id) LEFT JOIN billing.service_order_service_change AS bsosc ON (bsod.service_order_detail_id = bsosc.service_order_detail_id_new) LEFT JOIN service.exposure AS tse ON (tss.service_id = tse.service_id) WHERE service_order_detail_type_code = 'create' AND bsosc.service_order_detail_id_new IS NULL AND (tse.account_id = aa.account_id OR tse.account_id IS NULL);
signature.asc
Description: This is a digitally signed message part