2014-12-30 2 views
1

У меня есть этот запрос в моем PostgreSQL дбКак заставить объединение присоединиться?

UPDATE main_table m 
SET new_prod=false 
FROM reseller_product p 
WHERE p.distributor_id=896 
AND p.sku = m.sku 
AND p.reseller_id=8; 

И это занимает слишком много времени, чтобы выполнить. У меня есть индексы по столбцу sku в обеих таблицах. После использования команды EXPLAIN я увидел, что строгальный станок использовал Hash Join. Мне кажется, что Merge Join будет быстрее здесь. Я ошибаюсь ? Или, может быть, строгальный станок использовал Merge Join, потому что у запроса есть фильтры типа «p.distributor_id = 896»?

типа PS ы является характер изменения (50)

 
"Update (cost=80414.35..228437.71 rows=848460 width=212) (actual time=1582872.917..1582872.917 rows=0 loops=1)" 
" -> Hash Join (cost=80414.35..228437.71 rows=848460 width=212) (actual time=6906.044..23677.829 rows=706328 loops=1)" 
"  Hash Cond: ((p.sku)::text = (m.sku)::text)" 
"  -> Append (cost=0.00..96319.53 rows=1067877 width=20) (actual time=0.909..7426.880 rows=808287 loops=1)" 
"    -> Index Scan using res_prod_reseller_id on reseller_product p (cost=0.00..8.74 rows=1 width=20) (actual time=0.729..0.729 rows=0 loops=1)" 
"     Index Cond: (reseller_id = 8)" 
"     Filter: (distributor_id = 896)" 
"    -> Seq Scan on reseller_product_8 p (cost=0.00..96310.79 rows=1067876 width=20) (actual time=0.168..3850.121 rows=808287 loops=1)" 
"     Filter: ((distributor_id = 896) AND (reseller_id = 8))" 
"  -> Hash (cost=45779.60..45779.60 rows=848460 width=202) (actual time=6897.658..6897.658 rows=709948 loops=1)" 
"    Buckets: 1024 Batches: 256 Memory Usage: 417kB" 
"    -> Seq Scan on main_table m (cost=0.00..45779.60 rows=848460 width=202) (actual time=0.926..2770.997 rows=709948 loops=1)" 
+1

было бы лучше, если вы разместите план 'EXPLAIN' – Akash

+0

http://explain.depesz.com/s/z1m здесь – flgdev

+0

Можете ли вы также опубликовать оба определения таблиц? – Christian

ответ

0

ли sku столбцы main_table и reseller_product того же типа в обеих таблицах?

Имеет ли в вашем распоряжении индекс-реселлер?

CREATE INDEX I_reseller_product_1 ON reseller_product (distributor_id,reseller_id,sku); 

Имеет ли main_table индекс в столбце sku?

CREATE INDEX I_main_table_1  ON main_table  (sku); 

Если все вопросы да, попробуйте это:

UPDATE main_table m 
SET new_prod = false 
WHERE EXISTS (SELECT 1 
       FROM reseller_product p 
       WHERE p.distributor_id = 896 
       AND p.reseller_id = 8 
       AND p.sku   = m.sku 
       ); 
1

Ваш план упоминает, что вы обновляете около миллиона строк, selecting данных занимает 23 секунд, а updating и selecting их занимает 26 минут. updating их главная проблема, а не план используется для selecting он

MERGE JOIN было бы предпочтительнее, если вы в основном Упорядочивание результатов. В вашем случае HASH JOIN представляется подходящим выбором: почему планировщик тратит время, заказывая результаты, когда он не нужен. Вы могли бы заставить планировщика использовать MERGE JOIN, выпустив 'set enable_hashjoin = off', но скорее всего он сделает запрос медленнее.

Я подозреваю, любые Триггеры/индексирует на столе обновляется main_table или multi-column index's, которые содержат new_prod. Я бы предложил отключить триггер и/или добавить indexes после того, как вы закончите обновлять свои записи. Скорость чтения и записи также может зависеть от других факторов, с которых вам необходимо начать свое оборудование.

Смежные вопросы