У нас есть запрос в нашей БД, который выполняется намного медленнее, чем нам хотелось бы, и мы сузили его до двух столбцов в таблице, которые при добавлении к вычислению выбора значительно увеличивают время запроса ( 30-40 сек -> 5 мин 30 сек - 7 мин). Единственная интересная особенность этих столбцов заключается в том, что они в настоящее время содержат только NULL. В другой среде, где эти столбцы действительно содержат значения, у нас нет этой проблемы.
Структура запроса:
SELECT (some columns, calculations, etc)
FROM table_a
LEFT JOIN (
SELECT more columns, calculations, a + ONLY NULLS COLUMN + OTHER ONLY NULLS COLUMN + b
FROM view_a) alias_a
ON table_a.id = alias_a.id
GROUP BY alias_a.id.
Подзапрос выполняется нормально, а внешний запрос выполняется нормально пока мы удалим группировку . Не знаю, как исправить это, кроме вставки фиктивных данных.
объяснение плана (максимально анонимное)
GroupAggregate (cost=10432.09..11510.14 rows=4683 width=484)
Group Key: mc.id
-> Merge Left Join (cost=10432.09..10456.47 rows=4683 width=251)
Merge Cond: (mc.id = mct.macguffin_child_id)
-> Sort (cost=439.33..451.04 rows=4683 width=4)
Sort Key: mc.id
-> Seq Scan on macguffin_child mc (cost=0.00..153.83 rows=4683 width=4)
-> Sort (cost=9992.76..9992.92 rows=64 width=251)
Sort Key: mct.macguffin_child_id
-> Nested Loop Left Join (cost=5221.87..9990.84 rows=64 width=251)
-> Merge Join (cost=5221.44..9947.83 rows=64 width=211)
Merge Cond: (mp.id = m.phase_id)
Join Filter: (mc_1.macguffin_id = m.id)
-> Nested Loop (cost=4748.32..10792.40 rows=64 width=223)
-> Nested Loop (cost=4748.05..10788.94 rows=1 width=223)
-> Index Only Scan using macguffin_phase_pkey on macguffin_phase mp (cost=0.13..12.18 rows=3 width=4)
-> Materialize (cost=4747.92..10776.73 rows=1 width=219)
-> Gather (cost=4747.92..10776.72 rows=1 width=219)
Workers Planned: 1
-> Nested Loop (cost=3747.92..9776.62 rows=1 width=219)
-> Nested Loop (cost=3747.49..9625.65 rows=21 width=131)
-> Hash Join (cost=3747.07..9610.78 rows=21 width=121)
Hash Cond: ((mt.macguffin_id = mc_1.macguffin_id) AND (mct.macguffin_child_id = mc_1.id))
-> Parallel Hash Join (cost=3522.99..8897.48 rows=93186 width=100)
Hash Cond: (mct.macguffin_thing_id = mt.id)
-> Parallel Seq Scan on macguffin_child_thing mct (cost=0.00..2141.86 rows=93186 width=88)
-> Parallel Hash (cost=1966.11..1966.11 rows=89511 width=16)
-> Parallel Seq Scan on macguffin_thing mt (cost=0.00..1966.11 rows=89511 width=16)
-> Hash (cost=153.83..153.83 rows=4683 width=25)
-> Seq Scan on macguffin_child mc_1 (cost=0.00..153.83 rows=4683 width=25)
-> Index Scan using thing_pkey on thing t (cost=0.42..0.71 rows=1 width=26)
Index Cond: (id = mt.thing_id)
-> Index Scan using macguffin_thing_calculation_by_date_request_id_composite_key on macguffin_thing_calculation_by_date c (cost=0.43..7.18 rows=1 width=80)
Index Cond: ((request_id = mc_1.request_id) AND (sku = (t.sku)::text))
-> Index Only Scan using window_start_date_end_date_idx on window w (cost=0.28..2.83 rows=64 width=8)
Index Cond: ((start_date <= c.date) AND (end_date >= c.date))
-> Sort (cost=473.12..484.53 rows=4565 width=8)
Sort Key: m.phase_id
-> Seq Scan on macguffin m (cost=0.00..195.65 rows=4565 width=8)
-> Index Scan using macguffin_thing_calculation_override_thing_id on macguffin_thing_calculation_override mtco (cost=0.42..0.63 rows=1 width=21)
Index Cond: ((mct.macguffin_thing_id = macguffin_thing_id) AND (c.date = date))
Таблица, содержащая неправильные поля
-- auto-generated definition
CREATE TABLE macguffin_child_thing
(
id serial NOT NULL
CONSTRAINT macguffin_child_thing_pkey
PRIMARY KEY,
macguffin_child_id integer NOT NULL
CONSTRAINT macguffin_child_thing_macguffin_child_id_fkey
REFERENCES macguffin_child,
macguffin_thing_id integer NOT NULL
CONSTRAINT macguffin_child_thing_macguffin_thing_id_fkey
REFERENCES macguffin_thing,
thing_field_1 numeric
CONSTRAINT macguffin_child_thing_thing_field_check
CHECK (thing_field >= (0)::numeric),
some_value numeric,
thing_field_2 numeric =================================OFFENDING FIELD
CONSTRAINT macguffin_child_thing_thing_field_2_check
CHECK (thing_field_2 >= (0)::numeric),
thing_field_3 numeric =================================OFFENDING FIELD
CONSTRAINT macguffin_child_thing_thing_field_3_check
CHECK (thing_field_3 >= (0)::numeric),
thing_field_4 numeric
CONSTRAINT macguffin_child_thing_thing_field_4_check
CHECK (thing_field_4 >= (0)::numeric)
);
ALTER TABLE macguffin_child_thing
OWNER TO db_owner;
CREATE UNIQUE INDEX macguffin_child_thing__unique_idx
ON macguffin_child_thing (macguffin_child_id, macguffin_thing_id);