0

我正在使用 Postgres 8.4。我的系统配置是window 7 32 bit 4 gb ram和2.5ghz。

我在 Postgres 中有一个包含 10 个表的数据库t1, t2, t3, t4, t5.....t10

t1有一个主键和一个序列 id,它是对所有其他表的外键引用。

数据被插入到数据库中(即在所有表中),除了t1所有其他表有近50,000 行数据外,t1还有一个1 行,其主键是从所有其他表中引用的。然后我在 t1 中插入第二行数据,并在其他表中使用这个新引用再次插入 50,000 行。

问题是当我想删除其他表中存在的所有数据条目时:

delete from t1 where column1='1'

此查询需要将近 10 分钟才能执行。

我也创建了索引并尝试过,但性能并没有提高。可以做什么?

我在下面提到了一个示例架构

CREATE TABLE t1
(
  c1 numeric(9,0) NOT NULL,
  c2 character varying(256) NOT NULL,
  c3ver numeric(4,0) NOT NULL,
  dmlastupdatedate timestamp with time zone NOT NULL,
  CONSTRAINT t1_pkey PRIMARY KEY (c1),
  CONSTRAINT t1_c1_c2_key UNIQUE (c2)
);

CREATE TABLE t2
(
  c1 character varying(100),
  c2 character varying(100),
  c3 numeric(9,0) NOT NULL,
  c4 numeric(9,0) NOT NULL,
  tver numeric(4,0) NOT NULL,
  dmlastupdatedate timestamp with time zone NOT NULL,
  CONSTRAINT t2_pkey PRIMARY KEY (c3),
  CONSTRAINT t2_fk FOREIGN KEY (c4)
      REFERENCES t1 (c1) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE CASCADE,
  CONSTRAINT t2_c3_c4_key UNIQUE (c3, c4)
);

CREATE INDEX t2_index ON t2 USING btree (c4);

让我知道架构是否有任何问题。

4

1 回答 1

1

对于更大的表和不止两个或三个值,您需要在引用列 ( t1.c1) 以及引用列 ( t2.c4, ...) 上建立索引。

但是,如果您的描述是准确的,那不可能是您的方案中性能问题的原因。由于您在 中只有2 个不同的值t1,因此索引没有用处。顺序扫描会更快。

无论如何,我重新制定了你在 Postgres 9.1.9 中描述的内容

CREATE TABLE t1
( c1 numeric(9,0) PRIMARY KEY,
  c2 character varying(256) NOT NULL,
  c3ver numeric(4,0) NOT NULL,
  dmlastupdatedate timestamptz NOT NULL,
  CONSTRAINT t1_uni_key UNIQUE (c2)
);

CREATE temp TABLE t2
( c1 character varying(100),
  c2 character varying(100),
  c3 numeric(9,0) PRIMARY KEY,
  c4 numeric(9,0) NOT NULL,
  tver numeric(4,0) NOT NULL,
  dmlastupdatedate timestamptz NOT NULL,
  CONSTRAINT t2_uni_key UNIQUE (c3, c4),
  CONSTRAINT t2_c4_fk FOREIGN KEY (c4)
      REFERENCES t1(c1) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE CASCADE
);

INSERT INTO t1 VALUES 
 (1,'OZGPIGp7tgp97tßp97tß97tgP?)/GP)7gf', 234, now())
,(2,'agdsOZGPIGp7tgp97tßp97tß97tgP?)/GP)7gf', 4564, now());

INSERT INTO t2
SELECT'shOahaZGPIGp7tgp97tßp97tß97tgP?)/GP)7gf'
     ,'shOahaZGPIGp7tgp97tßp97tß97tgP?)/GP)7gf'
     , g, 2, 456, now()
from generate_series (1,50000) g

INSERT INTO t2
SELECT'shOahaZGPIGp7tgp97tßp97tß97tgP?)/GP)7gf'
     ,'shOahaZGPIGp7tgp97tßp97tß97tgP?)/GP)7gf'
     , g, 2, 789, now()
from generate_series (50001, 100000) g

ANALYZE t1;
ANALYZE t2;

EXPLAIN ANALYZE DELETE FROM t1 WHERE c1 = 1;

总运行时间:53.745 毫秒

DELETE FROM t1 WHERE c1 = 1;

58 毫秒的执行时间。

因此,您的架构布局根本没有问题

改进:

  • 您定义了几列numeric(9,0)numeric(4,0). 除非您有充分的理由这样做,否则您最好使用integer. 它们总体上更小更快。如果您确实需要强制执行最大值,您可以随时添加检查约束。

  • 我也会使用text而不是varchar(n)

  • 重新排序列(在创建表时)。根据经验,首先放置固定长度的 NOT NULL 列。把timestampand integerfirst and numericor textlast。更多在这里。.

于 2013-06-21T19:50:03.117 回答