PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Hướng dẫn phân vùng dữ liệu trong PostgreSQL

Phân vùng dữ liệu là gì?

Đối với cơ sở dữ liệu có các bảng cực lớn, phân vùng là một thủ thuật tuyệt vời và xảo quyệt cho các nhà thiết kế cơ sở dữ liệu để cải thiện hiệu suất cơ sở dữ liệu và làm cho việc bảo trì dễ dàng hơn nhiều. Kích thước bảng tối đa được phép trong cơ sở dữ liệu PostgreSQL là 32TB, tuy nhiên, trừ khi nó đang chạy trên một máy tính chưa được phát minh trong tương lai, các vấn đề về hiệu suất có thể phát sinh trên một bảng chỉ có một phần trăm dung lượng đó.

Việc phân vùng chia một bảng thành nhiều bảng và thường được thực hiện theo cách mà các ứng dụng truy cập vào bảng không nhận thấy bất kỳ sự khác biệt nào, ngoài việc truy cập nhanh hơn vào dữ liệu mà nó cần. Bằng cách chia bảng thành nhiều bảng, ý tưởng là cho phép việc thực thi các truy vấn phải quét các bảng và chỉ mục nhỏ hơn nhiều để tìm dữ liệu cần thiết. Bất kể chiến lược lập chỉ mục hiệu quả đến mức nào, việc quét chỉ mục cho một bảng có dung lượng 50GB sẽ luôn nhanh hơn nhiều so với chỉ mục cho một bảng có dung lượng 500GB. Điều này cũng áp dụng cho việc quét bảng, vì đôi khi việc quét bảng chỉ là không thể tránh khỏi.

Khi giới thiệu bảng được phân vùng với trình lập kế hoạch truy vấn, có một số điều cần biết và hiểu về chính trình lập kế hoạch truy vấn. Trước khi bất kỳ truy vấn nào thực sự được thực thi, trình lập kế hoạch truy vấn sẽ thực hiện truy vấn và lập kế hoạch theo cách hiệu quả nhất mà nó sẽ truy cập vào dữ liệu. Bằng cách phân chia dữ liệu thành các bảng khác nhau, người lập kế hoạch có thể quyết định những bảng nào cần truy cập và những bảng nào cần hoàn toàn bỏ qua, dựa trên những gì mỗi bảng chứa.

Điều này được thực hiện bằng cách thêm các ràng buộc vào các bảng được chia nhỏ để xác định dữ liệu nào được phép trong mỗi bảng và với một thiết kế tốt, chúng tôi có thể yêu cầu trình lập kế hoạch truy vấn quét một tập nhỏ dữ liệu thay vì toàn bộ.

Có nên phân vùng bảng không?

Việc phân vùng có thể cải thiện đáng kể hiệu suất trên bảng khi thực hiện đúng, nhưng nếu làm sai hoặc khi không cần thiết, nó có thể làm cho hiệu suất kém hơn, thậm chí không thể sử dụng được.

Cái bàn lớn bao nhiêu?

Không có quy tắc cứng thực sự nào về độ lớn của bảng trước khi phân vùng là một tùy chọn, nhưng dựa trên xu hướng truy cập cơ sở dữ liệu, người dùng và quản trị viên cơ sở dữ liệu sẽ bắt đầu thấy hiệu suất trên một bảng cụ thể bắt đầu giảm khi nó lớn hơn. Nói chung, việc phân vùng chỉ nên được xem xét khi ai đó nói "Tôi không thể làm X vì bảng quá lớn." Đối với một số máy chủ, 200 GB có thể là thời điểm thích hợp để phân vùng, đối với những máy khác, có thể đã đến lúc phân vùng khi nó đạt 1TB.

Nếu bảng được xác định là "quá lớn", đã đến lúc xem xét các kiểu truy cập. Bằng cách biết các ứng dụng truy cập cơ sở dữ liệu hoặc bằng cách theo dõi nhật ký và tạo báo cáo truy vấn với thứ gì đó như pgBadger, chúng ta có thể thấy cách một bảng được truy cập và tùy thuộc vào cách nó được truy cập, chúng ta có thể có các tùy chọn cho một chiến lược phân vùng tốt.

Để tìm hiểu thêm về pgBadger và cách sử dụng nó, vui lòng xem bài viết trước của chúng tôi về pgBadger.

Có phải bàn bị phồng là một vấn đề không?

Các hàng đã cập nhật và bị xóa dẫn đến các bộ dữ liệu chết và cuối cùng cần được dọn dẹp. Bàn hút bụi, dù theo cách thủ công hay tự động, sẽ đi qua mọi hàng trong bảng và xác định xem nó sẽ được thu hồi hay để một mình. Bảng càng lớn thì quá trình này càng mất nhiều thời gian và sử dụng nhiều tài nguyên hệ thống hơn. Ngay cả khi 90% của một bảng là dữ liệu không thay đổi, nó phải được quét mỗi khi chạy chân không. Phân vùng bảng có thể giúp giảm bảng cần hút bụi thành những bảng nhỏ hơn, giảm lượng dữ liệu không thay đổi cần được quét, ít thời gian hút bụi hơn và giải phóng nhiều tài nguyên hệ thống hơn cho người dùng truy cập thay vì bảo trì hệ thống.

Dữ liệu bị xóa như thế nào, nếu hoàn toàn?

Nếu dữ liệu bị xóa theo lịch trình, chẳng hạn như dữ liệu cũ hơn 4 năm bị xóa và lưu trữ, điều này có thể dẫn đến các câu lệnh xóa bị ảnh hưởng nặng nề và có thể mất thời gian để chạy và như đã đề cập trước đó, tạo ra các hàng chết cần được hút bụi. Nếu một chiến lược phân vùng tốt được thực hiện, câu lệnh DELETE kéo dài nhiều giờ với bảo trì hút bụi sau đó có thể được chuyển thành câu lệnh DROP TABLE một phút trên một bảng hàng tháng cũ mà không cần bảo trì chân không.

Bảng nên được phân vùng như thế nào?

Các khóa cho các mẫu truy cập nằm trong mệnh đề WHERE và điều kiện JOIN. Bất cứ khi nào một truy vấn chỉ định các cột trong mệnh đề WHERE và JOIN, nó sẽ cho cơ sở dữ liệu biết “đây là dữ liệu tôi muốn”. Giống như việc thiết kế các chỉ mục nhắm mục tiêu các mệnh đề này, chiến lược phân vùng dựa vào việc nhắm mục tiêu các cột này để phân tách dữ liệu và có quyền truy cập truy vấn càng ít phân vùng càng tốt.

Ví dụ:

  1. Một bảng giao dịch với cột ngày luôn được sử dụng trong mệnh đề where.
  2. Một bảng khách hàng với các cột vị trí, chẳng hạn như quốc gia cư trú luôn được sử dụng trong mệnh đề where.

Các cột phổ biến nhất cần tập trung vào để phân vùng thường là dấu thời gian, vì thường một lượng lớn dữ liệu là thông tin lịch sử và có khả năng sẽ có dữ liệu khá dễ dự đoán trải dài trên các nhóm thời gian khác nhau.

Xác định mức lan truyền dữ liệu

Sau khi xác định được cột nào cần phân vùng, chúng ta nên xem xét mức độ trải rộng của dữ liệu, với mục tiêu là tạo kích thước phân vùng giúp trải đều dữ liệu nhất có thể trên các phân vùng con khác nhau.

severalnines=# SELECT DATE_TRUNC('year', view_date)::DATE, COUNT(*) FROM website_views GROUP BY 1 ORDER BY 1;
 date_trunc |  count
------------+----------
 2013-01-01 | 11625147
 2014-01-01 | 20819125
 2015-01-01 | 20277739
 2016-01-01 | 20584545
 2017-01-01 | 20777354
 2018-01-01 |   491002
(6 rows)

Trong ví dụ này, chúng tôi cắt ngắn cột dấu thời gian thành một bảng hàng năm, dẫn đến khoảng 20 triệu hàng mỗi năm. Nếu tất cả các truy vấn của chúng tôi chỉ định (các) ngày hoặc (các) phạm vi ngày và những truy vấn được chỉ định thường bao gồm dữ liệu trong vòng một năm, thì đây có thể là một chiến lược khởi đầu tuyệt vời để phân vùng, vì nó sẽ dẫn đến một bảng duy nhất mỗi năm , với số lượng hàng có thể quản lý trên mỗi bảng.

Tải xuống Báo cáo chính thức hôm nay Quản lý &Tự động hóa PostgreSQL với ClusterControlTìm hiểu về những điều bạn cần biết để triển khai, giám sát, quản lý và mở rộng PostgreSQLTải xuống Báo cáo chính thức

Tạo bảng được phân vùng

Có một số cách để tạo bảng được phân vùng, tuy nhiên chúng tôi sẽ chủ yếu tập trung vào loại giàu tính năng nhất hiện có, phân vùng dựa trên kích hoạt. Điều này yêu cầu thiết lập thủ công và một chút mã hóa bằng ngôn ngữ thủ tục plpgsql để hoạt động.

Nó hoạt động bằng cách có một bảng mẹ cuối cùng sẽ trở nên trống (hoặc vẫn trống nếu đó là một bảng mới) và các bảng con QUẢN LÝ bảng mẹ. Khi bảng mẹ được truy vấn, các bảng con cũng được tìm kiếm dữ liệu do INHERIT được áp dụng cho các bảng con. Tuy nhiên, vì bảng con chỉ chứa các tập con dữ liệu của mẹ, chúng tôi thêm một CONSTRAINT trên bảng để KIỂM TRA và xác minh rằng dữ liệu khớp với những gì được phép trong bảng. Điều này thực hiện hai điều:Đầu tiên nó từ chối dữ liệu không thuộc về và thứ hai nó cho người lập kế hoạch truy vấn biết rằng chỉ dữ liệu khớp với CHECK CONSTRAINT này mới được phép trong bảng này, vì vậy nếu tìm kiếm dữ liệu không khớp với bảng, đừng ' thậm chí không cần phải tìm kiếm nó.

Cuối cùng, chúng tôi áp dụng một trình kích hoạt cho bảng mẹ thực thi một thủ tục được lưu trữ để quyết định bảng con nào sẽ đặt dữ liệu.

Tạo bảng

Tạo bảng cha giống như bất kỳ tạo bảng nào khác.

severalnines=# CREATE TABLE data_log (data_log_sid SERIAL PRIMARY KEY,
  date TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
  event_details VARCHAR);
CREATE TABLE

Tạo bảng con

Việc tạo bảng con cũng tương tự, nhưng có một số bổ sung. Vì lợi ích tổ chức, chúng tôi sẽ để các bảng con của chúng tôi tồn tại trong một giản đồ riêng biệt. Thực hiện việc này cho từng bảng con, thay đổi các chi tiết cho phù hợp.

LƯU Ý:Tên của trình tự được sử dụng trong giá trị tiếp theo () đến từ trình tự mà cha mẹ đã tạo. Điều này rất quan trọng để tất cả các bảng con sử dụng cùng một trình tự.

severalnines=# CREATE SCHEMA part;
CREATE SCHEMA

severalnines=# CREATE TABLE part.data_log_2018 (data_log_sid integer DEFAULT nextval('public.data_log_data_log_sid_seq'::regclass),
  date TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW(),
  event_details VARCHAR)
 INHERITS (public.data_log);
CREATE TABLE

severalnines=# ALTER TABLE ONLY part.data_log_2018
    ADD CONSTRAINT data_log_2018_pkey PRIMARY KEY (data_log_sid);
ALTER TABLE

severalnines=# ALTER TABLE part.data_log_2018 ADD CONSTRAINT data_log_2018_date CHECK (date >= '2018-01-01' AND date < '2019-01-01');
ALTER TABLE

Tạo chức năng và trình kích hoạt

Cuối cùng, chúng tôi tạo thủ tục được lưu trữ của mình và thêm trình kích hoạt vào bảng mẹ của chúng tôi.

severalnines=# CREATE OR REPLACE FUNCTION 
 public.insert_trigger_table()
  RETURNS trigger
  LANGUAGE plpgsql
 AS $function$
 BEGIN
     IF NEW.date >= '2018-01-01' AND NEW.date < '2019-01-01' THEN
         INSERT INTO part.data_log_2018 VALUES (NEW.*);
         RETURN NULL;
     ELSIF NEW.date >= '2019-01-01' AND NEW.date < '2020-01-01' THEN
         INSERT INTO part.data_log_2019 VALUES (NEW.*);
         RETURN NULL;
     END IF;
 END;
 $function$;
CREATE FUNCTION

severalnines=# CREATE TRIGGER insert_trigger BEFORE INSERT ON data_log FOR EACH ROW EXECUTE PROCEDURE insert_trigger_table();
CREATE TRIGGER

Kiểm tra nó ra

Bây giờ tất cả đã được tạo ra, hãy thử nghiệm nó. Trong thử nghiệm này, tôi đã thêm nhiều bảng hàng năm hơn từ 2013 - 2020.

Lưu ý:Câu trả lời chèn bên dưới là 'CHÈN 0 0', điều này có nghĩa là nó không chèn bất cứ thứ gì. Điều này sẽ được giải quyết ở phần sau của bài viết này.

severalnines=# INSERT INTO data_log (date, event_details) VALUES ('2018-08-20 15:22:14', 'First insert');
INSERT 0 0

severalnines=# SELECT * FROM data_log WHERE date >= '2018-08-01' AND date < '2018-09-01';
 data_log_sid |            date            | event_details
--------------+----------------------------+---------------
            1 | 2018-08-17 23:01:38.324056 | First insert
(1 row)

Nó tồn tại, nhưng hãy xem công cụ lập kế hoạch truy vấn để đảm bảo hàng đến từ bảng con chính xác và bảng mẹ hoàn toàn không trả về bất kỳ hàng nào.

severalnines=# EXPLAIN ANALYZE SELECT * FROM data_log;
                                                    QUERY PLAN
------------------------------------------------------------------------------------------------------------------
 Append  (cost=0.00..130.12 rows=5813 width=44) (actual time=0.016..0.019 rows=1 loops=1)
   ->  Seq Scan on data_log  (cost=0.00..1.00 rows=1 width=44) (actual time=0.007..0.007 rows=0 loops=1)
   ->  Seq Scan on data_log_2015  (cost=0.00..21.30 rows=1130 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2013  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2014  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2016  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2017  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2018  (cost=0.00..1.02 rows=2 width=44) (actual time=0.005..0.005 rows=1 loops=1)
   ->  Seq Scan on data_log_2019  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
   ->  Seq Scan on data_log_2020  (cost=0.00..17.80 rows=780 width=44) (actual time=0.001..0.001 rows=0 loops=1)
 Planning time: 0.373 ms
 Execution time: 0.069 ms
(12 rows)

Tin tốt, hàng duy nhất mà chúng tôi chèn đã hạ cánh trong bảng 2018, nơi nó thuộc về. Nhưng như chúng ta thấy, truy vấn không chỉ định mệnh đề where bằng cột ngày tháng, vì vậy để tìm nạp mọi thứ, trình lập kế hoạch và thực thi truy vấn đã quét tuần tự trên mỗi bảng.

Tiếp theo, hãy kiểm tra bằng cách sử dụng mệnh đề where.

severalnines=# EXPLAIN ANALYZE SELECT * FROM data_log WHERE date >= '2018-08-01' AND date < '2018-09-01';
                                                                   QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------
 Append  (cost=0.00..2.03 rows=2 width=44) (actual time=0.013..0.014 rows=1 loops=1)
   ->  Seq Scan on data_log  (cost=0.00..1.00 rows=1 width=44) (actual time=0.007..0.007 rows=0 loops=1)
         Filter: ((date >= '2018-08-01 00:00:00'::timestamp without time zone) AND (date < '2018-09-01 00:00:00'::timestamp without time zone))
   ->  Seq Scan on data_log_2018  (cost=0.00..1.03 rows=1 width=44) (actual time=0.006..0.006 rows=1 loops=1)
         Filter: ((date >= '2018-08-01 00:00:00'::timestamp without time zone) AND (date < '2018-09-01 00:00:00'::timestamp without time zone))
 Planning time: 0.591 ms
 Execution time: 0.041 ms
(7 rows)

Ở đây, chúng ta có thể thấy rằng trình lập kế hoạch và thực thi truy vấn đã thực hiện quét tuần tự trên hai bảng, bảng mẹ và bảng con cho năm 2018. Có các bảng con cho các năm 2013 - 2020, nhưng các bảng khác ngoài 2018 không bao giờ được truy cập vì mệnh đề where có một phạm vi chỉ thuộc về năm 2018. Công cụ lập kế hoạch truy vấn đã loại trừ tất cả các bảng khác vì CHECK CONSTRAINT cho rằng dữ liệu không thể tồn tại trong các bảng đó.

Phân vùng làm việc với Công cụ ORM nghiêm ngặt hoặc Xác thực hàng được chèn

Như đã đề cập trước đây, ví dụ mà chúng tôi đã tạo trả về ‘INSERT 0 0’ ngay cả khi chúng tôi đã chèn một hàng. Nếu các ứng dụng chèn dữ liệu vào các bảng được phân vùng này dựa vào việc xác minh rằng các hàng được chèn là chính xác, thì các hàng này sẽ không thành công. Có một bản sửa lỗi, nhưng nó thêm một lớp phức tạp khác vào bảng được phân vùng, vì vậy có thể bỏ qua nếu tình huống này không phải là vấn đề đối với các ứng dụng sử dụng bảng được phân vùng.

Sử dụng Chế độ xem thay vì bảng chính.

Cách khắc phục sự cố này là tạo một dạng xem truy vấn bảng mẹ và hướng các câu lệnh INSERT tới dạng xem. Việc chèn vào một chế độ xem nghe có vẻ điên rồ, nhưng đó chính là lúc để kích hoạt chế độ xem.

severalnines=# CREATE VIEW data_log_view AS 
 SELECT data_log.data_log_sid,
     data_log.date,
     data_log.event_details
    FROM data_log;
CREATE VIEW

severalnines=# ALTER VIEW data_log_view ALTER COLUMN data_log_sid SET default nextval('data_log_data_log_sid_seq'::regclass);
ALTER VIEW

Truy vấn dạng xem này sẽ giống như truy vấn bảng chính và mệnh đề WHERE cũng như JOINS sẽ hoạt động như mong đợi.

Xem chức năng và trình kích hoạt cụ thể

Thay vì sử dụng hàm và trình kích hoạt mà chúng ta đã xác định trước đó, cả hai sẽ hơi khác nhau. Các thay đổi được in đậm.

CREATE OR REPLACE FUNCTION public.insert_trigger_view()
 RETURNS trigger
 LANGUAGE plpgsql
AS $function$
BEGIN
    IF NEW.date >= '2018-01-01' AND NEW.date < '2019-01-01' THEN
        INSERT INTO part.data_log_2018 VALUES (NEW.*);
        RETURN NEW;

    ELSIF NEW.date >= '2019-01-01' AND NEW.date < '2020-01-01' THEN
        INSERT INTO part.data_log_2019 VALUES (NEW.*);
        RETURN NEW;

    END IF;
END;
$function$;

severalnines=# CREATE TRIGGER insert_trigger INSTEAD OF INSERT ON data_log_view FOR EACH ROW EXECUTE PROCEDURE insert_trigger_view();

Định nghĩa “INSTEAD OF” tiếp quản lệnh chèn trên dạng xem (cách này vẫn không hoạt động) và thực thi chức năng thay thế. Hàm mà chúng tôi đã xác định có một yêu cầu rất cụ thể là thực hiện "TRỞ LẠI MỚI;" sau khi quá trình chèn vào các bảng con hoàn tất. Nếu không có điều này (hoặc làm như chúng tôi đã làm trước đây với ‘RETURN NULL’) sẽ dẫn đến "INSERT 0 0" thay vì "INSERT 0 1" như chúng tôi mong đợi.

Ví dụ:

severalnines=# INSERT INTO data_log_view (date, event_details) VALUES ('2018-08-20 18:12:48', 'First insert on the view');
INSERT 0 1

severalnines=# EXPLAIN ANALYZE SELECT * FROM data_log_view WHERE date >= '2018-08-01' AND date < '2018-09-01';
                                                                   QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------
 Append  (cost=0.00..2.03 rows=2 width=44) (actual time=0.015..0.017 rows=2 loops=1)
   ->  Seq Scan on data_log  (cost=0.00..1.00 rows=1 width=44) (actual time=0.009..0.009 rows=0 loops=1)
         Filter: ((date >= '2018-08-01 00:00:00'::timestamp without time zone) AND (date < '2018-09-01 00:00:00'::timestamp without time zone))
   ->  Seq Scan on data_log_2018  (cost=0.00..1.03 rows=1 width=44) (actual time=0.006..0.007 rows=2 loops=1)
         Filter: ((date >= '2018-08-01 00:00:00'::timestamp without time zone) AND (date < '2018-09-01 00:00:00'::timestamp without time zone))
 Planning time: 0.633 ms
 Execution time: 0.048 ms
(7 rows)

severalnines=# SELECT * FROM data_log_view WHERE date >= '2018-08-01' AND date < '2018-09-01';
 data_log_sid |        date         |      event_details
--------------+---------------------+--------------------------
            1 | 2018-08-20 15:22:14 | First insert
            2 | 2018-08-20 18:12:48 | First insert on the view
(2 rows)

Các ứng dụng thử nghiệm xem "rowcount" đã chèn là chính xác sẽ thấy bản sửa lỗi này hoạt động như mong đợi. Trong ví dụ này, chúng tôi đã thêm _view vào chế độ xem và thủ tục được lưu trữ của chúng tôi, nhưng nếu bảng muốn được phân vùng mà không có bất kỳ người dùng nào biết / thay đổi ứng dụng, thì chúng tôi sẽ đổi tên bảng mẹ thành data_log_parent và gọi chế độ xem bằng cũ tên của bảng mẹ.

Cập nhật hàng và thay đổi giá trị cột được phân vùng

Một điều cần lưu ý là nếu thực hiện cập nhật dữ liệu trong bảng được phân vùng và thay đổi giá trị của cột thành thứ không được ràng buộc cho phép sẽ dẫn đến lỗi. Nếu loại cập nhật này sẽ không bao giờ xảy ra, thì có thể bỏ qua nó, nhưng nếu có khả năng xảy ra, một trình kích hoạt mới cho các quy trình CẬP NHẬT sẽ được viết để xóa hàng khỏi phân vùng con cũ và chèn một hàng mới vào phân vùng phân vùng con đích mới.

Tạo phân vùng trong tương lai

Việc tạo các phân vùng trong tương lai có thể được thực hiện theo một số cách khác nhau, mỗi cách đều có ưu và nhược điểm.

Trình tạo phân vùng trong tương lai

Một chương trình bên ngoài có thể được viết lên để tạo các phân vùng trong tương lai X trước khi chúng cần đến. Trong ví dụ về phân vùng được phân vùng vào một ngày, phân vùng cần thiết tiếp theo để tạo (trong trường hợp của chúng tôi là năm 2019) có thể được thiết lập để được tạo vào khoảng tháng 12. Đây có thể là một tập lệnh thủ công do Quản trị viên Cơ sở dữ liệu chạy hoặc được đặt để cron chạy nó khi cần thiết. Phân vùng hàng năm có nghĩa là nó chạy mỗi năm một lần, tuy nhiên các phân vùng hàng ngày là phổ biến và công việc cron hàng ngày giúp cho DBA hạnh phúc hơn.

Trình tạo phân vùng tự động

Với sức mạnh của plpgsql, chúng tôi có thể ghi lại lỗi nếu cố gắng chèn dữ liệu vào một phân vùng con không tồn tại và ngay lập tức hãy tạo phân vùng cần thiết, sau đó thử chèn lại. Tùy chọn này hoạt động tốt, ngoại trừ trường hợp nhiều máy khách khác nhau chèn dữ liệu tương tự vào cùng một lúc, có thể gây ra tình trạng chạy đua trong đó một máy khách tạo bảng, trong khi một máy khách khác cố gắng tạo cùng một bảng và gặp lỗi. Lập trình plpgsql thông minh và nâng cao có thể khắc phục điều này, nhưng liệu nó có xứng đáng với mức độ nỗ lực hay không thì còn phải tranh luận. Nếu điều kiện cuộc đua này không xảy ra do các mẫu chèn thì không có gì phải lo lắng.

Chia nhỏ các phân vùng

Nếu các quy tắc lưu giữ dữ liệu quy định rằng dữ liệu sẽ bị xóa sau một khoảng thời gian nhất định, thì điều này sẽ trở nên dễ dàng hơn với các bảng được phân vùng nếu được phân vùng trên một cột ngày tháng. Nếu chúng tôi muốn xóa dữ liệu đã 10 năm tuổi, thì có thể đơn giản như sau:

severalnines=# DROP TABLE part.data_log_2007;
DROP TABLE

Điều này nhanh hơn và hiệu quả hơn nhiều so với câu lệnh 'DELETE', vì nó không dẫn đến bất kỳ bộ giá chết nào khi làm sạch bằng máy hút.

Lưu ý:Nếu xóa bảng khỏi thiết lập phân vùng, mã trong các hàm kích hoạt cũng phải được thay đổi để không chuyển ngày trực tiếp đến bảng đã xóa.

Những điều cần biết trước khi phân vùng

Bảng phân vùng có thể cung cấp một sự cải thiện mạnh mẽ cho hiệu suất, nhưng nó cũng có thể làm cho nó tồi tệ hơn. Trước khi chuyển sang máy chủ sản xuất, chiến lược phân vùng nên được thử nghiệm rộng rãi, để biết tính nhất quán của dữ liệu, tốc độ hiệu suất, mọi thứ. Việc phân vùng bảng có một số bộ phận chuyển động, tất cả chúng phải được kiểm tra để đảm bảo không có vấn đề gì.

Khi quyết định số lượng phân vùng, chúng tôi khuyên bạn nên giữ số lượng bảng con dưới 1000 bảng và thậm chí thấp hơn nếu có thể. Khi số lượng bảng con vượt quá ~ 1000, hiệu suất bắt đầu giảm vì bản thân công cụ lập kế hoạch truy vấn sẽ mất nhiều thời gian hơn chỉ để lập kế hoạch truy vấn. Không phải là chưa từng có kế hoạch truy vấn mất nhiều giây, trong khi quá trình thực thi thực tế chỉ mất vài mili giây. Nếu việc xử lý hàng nghìn truy vấn trong một phút, vài giây có thể khiến các ứng dụng ngừng hoạt động.

Các thủ tục được lưu trữ kích hoạt plpgsql cũng có thể trở nên phức tạp và nếu quá phức tạp, cũng làm chậm hiệu suất. Thủ tục đã lưu trữ được thực thi một lần cho mỗi hàng được chèn vào bảng. Nếu nó kết thúc quá nhiều xử lý cho mỗi hàng, các lần chèn có thể trở nên quá chậm. Kiểm tra hiệu suất sẽ đảm bảo rằng nó vẫn nằm trong phạm vi có thể chấp nhận được.

Sáng tạo

Các bảng phân vùng trong PostgreSQL có thể nâng cao nếu cần. Thay vì cột ngày, các bảng có thể được phân vùng trên cột "quốc gia", với một bảng cho mỗi quốc gia. Việc phân vùng có thể được thực hiện trên nhiều cột, chẳng hạn như cả cột "ngày tháng" và cột "quốc gia". Điều này sẽ làm cho quy trình đã lưu trữ xử lý các phần chèn phức tạp hơn, nhưng 100% là có thể.

Hãy nhớ rằng, mục tiêu của phân vùng là chia các bảng cực kỳ lớn thành các bảng nhỏ hơn và làm điều đó một cách có suy nghĩ thấu đáo để cho phép người lập kế hoạch truy vấn truy cập vào dữ liệu nhanh hơn những gì có thể có trong bảng gốc lớn hơn.

Phân vùng khai báo

Trong PostgreSQL 10 trở lên, một tính năng phân vùng mới 'Phân vùng khai báo' đã được giới thiệu. Đây là một cách dễ dàng hơn để thiết lập phân vùng, tuy nhiên có một số hạn chế. Nếu các hạn chế này có thể chấp nhận được, nó có thể sẽ hoạt động nhanh hơn so với thiết lập phân vùng thủ công, nhưng số lượng lớn thử nghiệm sẽ xác minh điều đó.

Tài liệu postgresql chính thức có thông tin về Phân vùng khai báo và cách nó hoạt động. Nó là điểm mới trong PostgreSQL 10 và với phiên bản 11 của PostgreSQL ở thời điểm viết bài này, một số hạn chế đã được khắc phục, nhưng không phải tất cả chúng. Khi PostgreSQL phát triển, Phân vùng Khai báo có thể trở thành một sự thay thế hoàn toàn cho phân vùng phức tạp hơn được đề cập trong bài viết này. Cho đến lúc đó, Phân vùng khai báo có thể là một giải pháp thay thế dễ dàng hơn nếu không có giới hạn nào hạn chế nhu cầu phân vùng.

Giới hạn phân vùng khai báo

Tài liệu PostgreSQL giải quyết tất cả các hạn chế với kiểu phân vùng này trong PostgreSQL 10, nhưng có thể tìm thấy tổng quan tuyệt vời trên The Official PostgreSQL Wiki liệt kê các hạn chế ở định dạng dễ đọc hơn, cũng như lưu ý những hạn chế nào đã được sửa trong PostgreSQL 11. sắp tới

Hỏi cộng đồng

Quản trị viên Cơ sở dữ liệu trên toàn cầu đã thiết kế các chiến lược phân vùng nâng cao và tùy chỉnh trong một thời gian dài, và nhiều người trong chúng ta tham gia IRC và danh sách gửi thư. Nếu cần trợ giúp để quyết định chiến lược tốt nhất hoặc chỉ cần giải quyết một lỗi trong quy trình đã lưu trữ, cộng đồng luôn sẵn sàng trợ giúp.

  • IRC
    Freenode có một kênh rất tích cực gọi là #postgres, nơi người dùng giúp nhau hiểu các khái niệm, sửa lỗi hoặc tìm các tài nguyên khác.
  • Danh sách Gửi thư
    PostgreSQL có một số danh sách gửi thư có thể được tham gia. Các câu hỏi / vấn đề dạng dài hơn có thể được gửi tại đây và có thể tiếp cận nhiều người hơn IRC tại bất kỳ thời điểm nào. Bạn có thể tìm thấy danh sách trên Trang web PostgreSQL và danh sách pgsql-general hoặc pgsql-admin là những nguồn tốt.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chuyển dự án Django từ backend sqlite3 sang postgresql bị lỗi khi tải datadump

  2. Cách statement_timestamp () hoạt động trong PostgreSQL

  3. Làm cách nào để đưa kết quả 0/0 vào COUNT tổng hợp?

  4. Lỗi postgres khi chèn - LỖI:chuỗi byte không hợp lệ để mã hóa UTF8:0x00

  5. cột postgres X không tồn tại