Tôi đang thiết lập cơ sở dữ liệu PostgreSQL 9 mới chứa hàng triệu (hoặc có thể là hàng tỷ) hàng. Vì vậy, tôi quyết định phân vùng dữ liệu bằng cách sử dụng thừa kế PostgreSQL.Chọn đúng quy tắc phân vùng
Tôi tạo ra một bảng tổng thể như thế này (đơn giản hóa ví dụ):
CREATE TABLE mytable
(
user_id integer,
year integer,
CONSTRAINT pk_mytable PRIMARY KEY (user_id, year)
);
Và 10 phân vùng bảng:
CREATE TABLE mytable_0() INHERITS (mytable);
CREATE TABLE mytable_1() INHERITS (mytable);
...
CREATE TABLE mytable_9() INHERITS (mytable);
Tôi biết rằng hàng sẽ luôn luôn được truy cập từ các ứng dụng bằng cách sử dụng độc đáo điều kiện user_id. Vì vậy, tôi muốn truyền dữ liệu "khá" bằng nhau trên 10 bảng bằng cách sử dụng một quy tắc dựa trên user_id.
Để truy vấn điều chỉnh trên bảng tổng thể, ý tưởng đầu tiên của tôi là sử dụng một hạn chế kiểm tra mô đun:
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);
...
Vấn đề là, khi tôi truy vấn bảng tổng thể "mytable" với điều kiện trên user_id, PostgreSQL phân tích rà soát tất cả các bảng và không được hưởng lợi từ ràng buộc kiểm tra:
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)"
trong khi đó nếu tôi sử dụng một hạn chế kiểm tra cổ điển như thế này (và các phân vùng lại phù hợp với quy tắc đó):
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);
...
nó sẽ quét chỉ bảng phù hợp với điều kiện (mytable và mytable_1 trong ví dụ này):
"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)"
Nhưng sử dụng ràng buộc kiểm tra như vậy rất khó để duy trì vì phạm vi của người sử dụng mà sẽ được áp dụng trong các bảng sẽ thay đổi qua các năm. hàng ngàn đầu tiên, có thể là hàng triệu hoặc nhiều hơn trong tương lai gần ...
Quy tắc nào tôi có thể sử dụng để phân vùng dữ liệu của mình trên 10 bảng có thể hưởng lợi từ ràng buộc kiểm tra để SELECT trên bảng chính sẽ chỉ quét cái bàn bên phải ...?
Cảm ơn, Nico