PostgreSQL 19: Những tính năng mới nổi bật và trải nghiệm thực chiến

07 tháng 9, 2026·7 phút đọc

PostgreSQL 19, dự kiến phát hành chính thức vào khoảng tháng 9 hoặc 10 năm 2026, hiện đang trong giai đoạn beta và mang đến nhiều cải tiến lớn. Bài viết này là một bản hướng dẫn thực hành, đưa bạn khám phá các tính năng 'hot' nhất như hỗ trợ chuẩn SQL/PGQ cho đồ thị, thao tác dữ liệu theo khoảng thời gian, tối ưu hóa hiệu suất đáng kể và những thay đổi quan trọng về mặc định mà người quản trị cần biết.

PostgreSQL 19: Những tính năng mới nổi bật và trải nghiệm thực chiến

PostgreSQL 19 đang ở giai đoạn beta, dự kiến phát hành chính thức vào khoảng tháng 9 hoặc 10 năm 2026. Trong bài viết này, chúng ta sẽ cùng nhau khám phá những tính năng nổi bật nhất của phiên bản này, dựa trên các bản phát hành thử nghiệm và phân tích mã nguồn, để có cái nhìn sớm nhất về những gì sẽ đến.

Tổng quan về PostgreSQL 19Tổng quan về PostgreSQL 19

Điểm nhấn: Hỗ trợ đồ thị với SQL/PGQ

Đây là tính năng đáng chú ý nhất của bản phát hành này. PostgreSQL 19 triển khai SQL/PGQ (Property Graph Query), một phần của chuẩn SQL:2023. Bạn có thể khai báo một đồ thị thuộc tính trên các bảng hiện có và truy vấn bằng cách khớp mẫu thay vì tự viết các câu lệnh JOIN.

Ví dụ, với hai bảng thông thường, chúng ta có thể tạo một đồ thị xã hội:

CREATE TABLE person (id int PRIMARY KEY, name text);
CREATE TABLE follows (src int REFERENCES person, dst int REFERENCES person);

Không có dữ liệu nào bị sao chép. social hoạt động như một đối tượng dạng view, khai báo rằng các dòng của bảng person là các đỉnh, và các dòng của bảng follows là các cạnh. Giờ đây, bạn có thể khớp các mẫu với mệnh đề GRAPH_TABLE, nơi -[...]-> đại diện cho một cạnh có hướng.

Sức mạnh thực sự nằm ở các mẫu nhiều chặng. Ví dụ, để tìm bạn của bạn bè:

SELECT persona.name, personb.name
FROM GRAPH_TABLE (social
  MATCH (persona)-[follows]->(intermediate)<-[follows]-(personb)
  COLUMNS (persona.id AS a_id, personb.id AS b_id)
) AS fof
JOIN person persona ON persona.id = fof.a_id
JOIN person personb ON personb.id = fof.b_id;

Điểm mấu chốt là không có engine thực thi mới nào được tạo ra. GRAPH_TABLE được viết lại thành một truy vấn quan hệ thông thường, vì vậy các kế hoạch, thống kê và lựa chọn chỉ mục bạn đã biết đều được áp dụng.

Điểm hạn chế đầu tiên là phiên bản này không hỗ trợ các đường dẫn có độ dài biến thiên. Các bộ định lượng như -[IS follows]->{1,3} sẽ bị từ chối với lỗi element pattern quantifier is not supported.

Cập nhật và xóa dữ liệu theo khoảng thời gian với FOR PORTION OF

Mệnh đề mới FOR PORTION OF trong UPDATEDELETE cho phép bạn thao tác trên một phần của cột dữ liệu dạng khoảng thời gian. Thay vì viết lại toàn bộ một chu kỳ hiệu lực, bạn có thể chỉ định một khoảng thời gian con và PostgreSQL sẽ tự động chia tách các dòng dữ liệu.

Giả sử chúng ta có một bảng lưu giá sản phẩm theo thời gian:

CREATE TABLE product_price (
  product_id int,
  price numeric,
  valid_period daterange,
  PRIMARY KEY (product_id, valid_period)
);

Bảng bắt đầu với một dòng: một mức giá có hiệu lực cho cả năm 2026. Để thay đổi giá chỉ cho tháng Bảy:

UPDATE product_price
SET price = 150
FOR PORTION OF valid_period FROM '2026-07-01' TO '2026-08-01'
WHERE product_id = 1;

Kết quả là một dòng ban đầu sẽ được tách thành ba dòng. Các khoảng thời gian không bị ảnh hưởng vẫn giữ giá cũ, và một dòng mới với giá mới được chèn vào giữa.

DELETE hoạt động tương tự, nhưng thay vì tách, nó sẽ cắt bỏ đi phần chỉ định:

DELETE FROM product_price
FOR PORTION OF valid_period FROM '2026-12-01' TO NULL
WHERE product_id = 1;

Ở đây, NULL như một giới hạn có nghĩa là "không giới hạn", vì vậy lệnh này sẽ xóa phần từ tháng 12 trở đi.

Tránh lỗ hổng với ON CONFLICT DO SELECT

Câu lệnh INSERT ... ON CONFLICT DO NOTHING ... RETURNING luôn có một lỗ hổng khó chịu: các dòng gây ra xung đột sẽ không xuất hiện trong kết quả, khiến bạn không thể biết chúng "đã tồn tại" hay "chưa từng được tạo". PostgreSQL 19 bổ sung ON CONFLICT DO SELECT để trả về các dòng hiện có mà không cần sửa đổi chúng.

INSERT INTO widget (id, qty) VALUES (1, 1)
ON CONFLICT (id) DO SELECT
RETURNING id, qty;

Cả hai trường hợp (thành công và xung đột) đều trả về dữ liệu. Với dòng xung đột, nó sẽ trả về giá trị hiện có trong bảng chứ không phải giá trị bạn cố chèn. Nó cũng cho phép bạn phân biệt hai loại dòng bằng cách sử dụng mệnh đề khóa như FOR UPDATE, vì việc khóa sẽ đánh dấu dòng đó.

Tối ưu hóa hiệu suất đáng chú ý

IGNORE NULLS trong các hàm Window

Các hàm lead(), lag(), first_value(), last_value()nth_value() giờ đây hỗ trợ mệnh đề IGNORE NULLS theo chuẩn SQL. Điều này rất hữu ích cho việc xử lý dữ liệu thưa thớt, ví dụ như cảm biến chỉ ghi nhận khi nhiệt độ thay đổi. Trước đây, để làm được điều này cần một truy vấn con phức tạp, giờ chỉ là một từ khóa đơn giản.

Lệnh REPACK thay thế VACUUM FULLCLUSTER

VACUUM FULLCLUSTER gần như làm cùng một việc (ghi lại bảng để thu hồi không gian) nhưng có hai cái tên gây nhầm lẫn và không có cách nào để tránh khóa ACCESS EXCLUSIVE. PostgreSQL 19 hợp nhất chúng dưới một lệnh duy nhất là REPACK.

Điểm quan trọng nhất là tùy chọn CONCURRENTLY mới, cho phép xây dựng lại bảng mà không cần khóa ACCESS EXCLUSIVE. Nó hoạt động bằng cách giải mã các thay đổi diễn ra trong quá trình xây dựng lại và phát lại chúng, do đó các thao tác đọc và ghi vẫn có thể tiếp tục diễn ra.

Eager Aggregation: Tối ưu hóa các truy vấn có JOIN và GROUP BY

Khi bạn nhóm theo một cột từ một phía của phép nối, bộ lập kế hoạch truy vấn giờ đây có thể đẩy một phần phép gom nhóm (Partial HashAggregate) xuống dưới phép nối. Việc này giúp giảm số lượng hàng mà phép nối phải xử lý. Ví dụ, một bảng có 100.000 hàng và 100 giá trị dim_id riêng biệt sẽ được gom nhóm còn 100 hàng trước khi thực hiện phép nối.

Cải thiện hiệu suất đáng kể cho NOT IN (subquery)

NOT IN (subquery) vốn là một cái bẫy hiệu suất kinh điển. Do logic ba giá trị của SQL, việc tối ưu hóa truy vấn này rất khó khăn nếu không chứng minh được subquery không trả về NULL. PostgreSQL 19 có thể chứng minh điều này khi cả hai cột đều có ràng buộc NOT NULL, cho phép chuyển đổi thành một phép anti-join hiệu quả hơn nhiều so với hashed subplan trước đây.

Thay đổi và tính năng đáng chú ý khác

Các mặc định quan trọng đã thay đổi

  • Tắt JIT theo mặc định: Lý do là chi phí biên dịch thường không đáng với các truy vấn ngắn, chỉ thực sự có lợi cho các truy vấn phân tích dài và phức tạp.
  • Nén TOAST mặc định là lz4: Nhanh hơn đáng kể so với pglz về cả thời gian nén và giải nén.
  • Bật log_lock_waits: Giúp bạn dễ dàng phát hiện và điều tra các vấn đề về tranh chấp khóa.
  • Tăng gấp đôi max_locks_per_transaction: Do việc phân bổ bộ nhớ dùng chung trở nên chính xác hơn.
  • Loại bỏ hỗ trợ RADIUS: Giao thức xác thực này đã bị loại bỏ.

Các tính năng quản trị hữu ích

  • Tự động VACUUM được ưu tiên theo điểm số thay vì thứ tự ngẫu nhiên: Mỗi bảng sẽ có một "điểm" thể hiện mức độ khẩn cấp, giúp các bảng có nguy cơ bị lỗi wraparound được xử lý trước. Một view mới được thêm vào để hiển thị chi tiết cách tính điểm này.
  • EXPLAIN có tùy chọn IO mới: Báo cáo chi tiết về hoạt động I/O bất đồng bộ (AIO) đã thực hiện, giúp bạn hiểu rõ hơn về hiệu suất đọc và ghi.

Lời kết

PostgreSQL 19 là một bản phát hành lớn và thú vị. Những thay đổi về mặc định (JIT tắt, nén lz4) đòi hỏi người quản trị nên đọc kỹ hướng dẫn về quá trình nâng cấp trước khi thực hiện. Việc nắm bắt sớm các tính năng mới sẽ giúp bạn tận dụng tối ưu sức mạnh của cơ sở dữ liệu này.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗