我設置的是將包含行的數百萬(或數十億可能)一個新的PostgreSQL 9數據庫。所以我決定使用PostgreSQL繼承分區數據。選擇正確的分區規則
我創建了一個主表這樣的(簡化的舉例):
CREATE TABLE mytable
(
user_id integer,
year integer,
CONSTRAINT pk_mytable PRIMARY KEY (user_id, year)
);
而10的分區表:
CREATE TABLE mytable_0() INHERITS (mytable);
CREATE TABLE mytable_1() INHERITS (mytable);
...
CREATE TABLE mytable_9() INHERITS (mytable);
我知道行將總是從使用唯一的應用程序訪問user_id條件。 因此,我想使用基於user_id的規則在10個表格上「相當」地分佈數據。
要在主表優化查詢,我的第一個想法是使用一個模檢查約束:
ALTER TABLE mytable_0 ADD CONSTRAINT mytable_user_id_check CHECK (user_id % 10 = 0);
ALTER TABLE mytable_1 ADD CONSTRAINT mytable_user_id_check CHECK (user_id % 10 = 1);
...
的問題是,當我查詢主表「MYTABLE」與USER_ID,PostgreSQL的條件分析檢查所有的表,不從檢查約束受益:
EXPLAIN SELECT * FROM mytable WHERE user_id = 12345;
"Result (cost=0.00..152.69 rows=64 width=36)"
" -> Append (cost=0.00..152.69 rows=64 width=36)"
" -> Seq Scan on mytable (cost=0.00..25.38 rows=6 width=36)"
" Filter: (user_id = 12345)"
" -> Seq Scan on mytable_0 mytable (cost=0.00..1.29 rows=1 width=36)"
" Filter: (user_id = 12345)"
" -> Seq Scan on mytable_1 mytable (cost=0.00..1.52 rows=1 width=36)"
" Filter: (user_id = 12345)"
...
" -> Seq Scan on mytable_9 mytable (cost=0.00..1.52 rows=1 width=36)"
" Filter: (user_id = 12345)"
而如果我用一個經典的檢查約束這樣的(和匹配規則,即重新分配):
ALTER TABLE mytable_0 ADD CONSTRAINT mytable_user_id_check CHECK (user_id BETWEEN 1 AND 10000);
ALTER TABLE mytable_1 ADD CONSTRAINT mytable_user_id_check CHECK (user_id BETWEEN 10001 AND 20000);
...
它會掃描只匹配條件(mytable的和mytable_1在本例中),該表:
"Result (cost=0.00..152.69 rows=64 width=36)"
" -> Append (cost=0.00..152.69 rows=64 width=36)"
" -> Seq Scan on mytable (cost=0.00..25.38 rows=6 width=36)"
" Filter: (user_id = 12345)"
" -> Seq Scan on mytable_1 mytable (cost=0.00..1.52 rows=1 width=36)"
" Filter: (user_id = 12345)"
但是,使用這樣的檢查約束難以維持,因爲這將在被填充的用戶範圍表格將在多年內發生變化。成千上萬的第一,甚至幾百萬或更多在不久的將來...
我可以用什麼規則來劃分同樣我了,可以受益於一個檢查約束,以便在主表中的SELECT將只掃描了10個表中的數據正確的桌子......?
感謝, 尼科