1

我努力通过垂直分区优化我的表的性能。以下 Select 语句应该从 postgre imho 中得到更多优化:

SELECT 
  "ProductView".name, 
  "ProductView".price, 
  "ProductView".pid
FROM 
  "DefaultSchema"."ProductView";

我的架构如下所示:

tables:
ProductA(**pid**, name, price)
ProductB(**pid**, desc)
view:
Product(**pid**,name, price, desc)

SQL:

CREATE TABLE "DefaultSchema"."ProductA"
(
  pid integer NOT NULL,
  price integer,
  name text,
  CONSTRAINT pk_pa PRIMARY KEY (pid)
)

CREATE TABLE "DefaultSchema"."ProductB"
(
  pid integer NOT NULL,
  "desc" text,
  CONSTRAINT "PK_PB" PRIMARY KEY (pid),
  CONSTRAINT "FK_PID" FOREIGN KEY (pid)
      REFERENCES "DefaultSchema"."ProductA" (pid) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE CASCADE
)

CREATE OR REPLACE VIEW "DefaultSchema"."ProductView" AS 
 SELECT p1.pid,
    p1.price,
    p1.name,
    p2."desc"
   FROM "DefaultSchema"."ProductA" p1
     JOIN "DefaultSchema"."ProductB" p2 ON p1.pid = p2.pid;

因此,您可能会认识到我并不真的需要 ProductB 来进行选择查询。然而,正如您在此处看到的,它在执行过程中被加入。

"Hash Join  (cost=36.10..74.61 rows=1160 width=40) (actual time=0.090..0.105 rows=7 loops=1)"
"  Hash Cond: (p2.pid = p1.pid)"
"  ->  Seq Scan on "ProductB" p2  (cost=0.00..22.30 rows=1230 width=4) (actual time=0.022..0.027 rows=7 loops=1)"
"  ->  Hash  (cost=21.60..21.60 rows=1160 width=40) (actual time=0.030..0.030 rows=7 loops=1)"
"        Buckets: 1024  Batches: 1  Memory Usage: 1kB"
"        ->  Seq Scan on "ProductA" p1  (cost=0.00..21.60 rows=1160 width=40) (actual time=0.010..0.017 rows=7 loops=1)"
"Total runtime: 0.299 ms"

我的问题是如何强制 postgre 只扫描 ProductA?我是否需要额外的约束,编辑配置文件,还是无法通过 postgre 中的垂直分区获得性能优势?提前非常感谢。:)

4

1 回答 1

1

PostgreSQL 的查询计划器还没有对内部连接进行连接删除。

您可以单独查询“ProductA”,也可以重写视图以使用左外连接。PostgreSQL 9.0+确实对左外连接进行了连接删除。

CREATE OR REPLACE VIEW "DefaultSchema"."ProductView" AS 
 SELECT p1.pid,
    p1.price,
    p1.name,
    p2."desc"
   FROM "DefaultSchema"."ProductA" p1
   LEFT JOIN "DefaultSchema"."ProductB" p2 ON p1.pid = p2.pid;

explain analyze
SELECT "ProductView".name, "ProductView".price, "ProductView".pid
FROM "ProductView";
查询计划
--
“ProductA”p1 上的 Seq Scan(成本=0.00..20.00 行=1000 宽度=41)(实际时间=0.008..0.225 行=1000 循环=1)

在每个应用程序中重写以使用左外连接并不安全,但我认为它对于您的特定问题是安全的。

于 2014-11-05T16:34:07.897 回答