Postgres表现不佳UNION ALL + INNER JOIN

时间:2018-07-02 10:23:58

标签: postgresql performance indexing

在以下情况下,Postgres查询的执行速度非常慢。谁能帮助我指出问题的原因或这种现象的原因?

我有3个不同的平台,每个平台都使用两个结构相同的表:

  1. 订单(每个平台的所有订单信息)
  2. order_product(每个订单购买的所有产品=每个平台的客户篮子)

还有一个全局产品表,其中包含所有平台上的产品信息:

  1. 产品

    CREATE TABLE产品(       product_id字符变化(64),       product_name字符变化(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" ;

..

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'

我认为查询计划中有问题的部分看起来像这样。尽管存在product_id的索引,但Postgres仍对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");

0 个答案:

没有答案
相关问题