2013-06-21 81 views
0

我正在使用Postgres 8.4。我的系統配置是窗口7 32位4 GB RAM和2.5GHZ。ON DELETE CACADE很慢

我在Postgres有一個數據庫,有10個表t1, t2, t3, t4, t5.....t10

t1有一個主鍵序列id,它是對所有其他表的外鍵引用。

的數據被插入在數據庫(即所有表中)除了t1所有其他表具有近50000行的數據,但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); 

一個示例模式讓我知道如果有什麼不對的架構。

+0

而不考慮其他表的定義,這是不可能知道的,但它可能是由於對例如缺失索引't2(t1_id)'或任何引用字段被命名。 –

+0

其他表與t2相同,但沒有更多列。現在我已經刪除了idexes – user2509885

+2

「你現在已經刪除了idexes」是什麼意思?我們需要查看相關列的索引,它們是必不可少的。與所有*可能涉及的其他約束和觸發器一起。另外:您的約束名稱非常具有誤導性。當你在這裏發佈或在你的數據庫中發佈時,你是否把它們搞亂了 –

回答

1

對於較大的表格和超過兩個或三個值,您需要在引用列(t1.c1)以及引用列(t2.c4,...)上的索引。

但是,如果您的描述是準確的,那麼可以而不是是您的方案中性能問題的原因。由於您在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毫秒的執行時間。

Ergo,有沒有什麼根本性的錯誤與您的架構佈局

增強:

  • 你有幾個列的定義numeric(9,0)numeric(4,0)。除非你有充分的理由這樣做,否則使用integer可能會好很多。它們整體更小更快。如果您確實需要強制執行最大值,則可以隨時添加檢查約束。

  • 我也要use text instead of varchar(n)

  • 而且重新排序列(在創建表時)。根據經驗,首先放置固定長度的NOT NULL列。首先將timestampintegernumerictext最後。 More here.

+0

那麼數值(9,0)和數字(4,0)變爲整數會如何影響性能?改變後我應該保留一個索引,並參見 – user2509885

+0

@ user2509885:這肯定會影響性能,但只是次要方面。您所報告的10分鐘運行時間必須來自不屬於您的問題的內容。 –

+0

確定還有一件事我想問我是否正確創建索引?並且我們可以在創建表之後在我們開始轉儲數據之前添加索引 – user2509885