Postgres плохая производительность UNION ALL + INNER JOIN - PullRequest
0 голосов
/ 02 июля 2018

В следующем сценарии запрос Postgres выполняется очень медленно. Может ли кто-нибудь помочь мне определить проблему или причину такого поведения?

У меня есть 3 разные платформы, каждая использует две таблицы одинаковой структуры:

  1. заказ (вся информация о заказе на платформу)
  2. order_product (все товары, приобретенные в каждом заказе = корзины клиентов для каждой платформы)

И есть также глобальная таблица продуктов, которая содержит информацию о продуктах для всех платформ:

  1. Продукт

    CREATE TABLE product ( символ product_id меняется (64), имя_продукта различно (512));

У меня также есть представления, объединяющие все таблицы order и order_product со всех платформ с UNION ALL.

CREATE VIEW order_product_all_platforms AS
SELECT "platform", "order_id", "product_id" 
FROM "public"."order_product_1"
UNION ALL 
SELECT "platform", "order_id", "product_id" 
FROM "public"."order_product_2"
UNION ALL 
SELECT "platform", "order_id", "product_id" 
FROM "public"."order_product_3" ;

.. * * 1023

CREATE VIEW order_all_platforms AS
SELECT "platform", "order_id", "purchase_date" 
FROM "public"."order_1"
UNION ALL 
SELECT "platform", "order_id", "purchase_date" 
FROM "public"."order_2"
UNION ALL 
SELECT "platform", "order_id", "purchase_date" 
FROM "public"."order_3" 

Проблема возникает, когда я хочу объединить все эти три таблицы в запросе так:

 SELECT "t1.platform", "t1.order_id", t2.product_id, t3.product_name
    FROM order_all_platforms t1 
      INNER JOIN order_product_all_platforms t2 ON t1.platform = t2.platform and t1.order_id = t2.order_id
      INNER JOIN product t3 ON t2.product_id = t3.product_id
 WHERE purchase_date >= '2018-01-01'

Я думаю, что проблемная часть плана запроса выглядит следующим образом. Postgres выполняет последовательное сканирование product_id, несмотря на то, что существует индекс product_id:

->  Hash Join  (cost=23068.58..1963856.51 rows=37164213 width=67)"
        Hash Cond: ((t2.product_id)::text = (t3.product_id)::text)"
        ->  Append  (cost=0.00..1104593.13 rows=37164213 width=29)"
              ->  Seq Scan on order_product_table1 (cost=0.00..1066147.91 rows=35935991 width=29)"
              ->  Seq Scan on order_product_table2 (cost=0.00..35008.37 rows=1126337 width=32)"
              ->  Seq Scan on order_product_table3 (cost=0.00..3436.85 rows=101885 width=30)"
        ->  Hash  (cost=16209.37..16209.37 rows=548737 width=47)"
              ->  Seq Scan on product t3 (cost=0.00..16209.37 rows=548737 width=47)"

Что я могу сделать, чтобы ускорить это?

Это индексы. Первый индекс также существует в таблице заказов, второй индекс также существует в таблице продуктов:

CREATE INDEX  order_product_table1_index1
  ON  order_product_table1
  USING btree
  (platform_name COLLATE pg_catalog."default", order_id);  

CREATE INDEX mat_ order_product_table1_index2
  ON  order_product_table1
  USING btree
  (product_id COLLATE pg_catalog."default");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...