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

Đối sánh phân vùng nâng cao để tham gia phân vùng khôn ngoan

Trước đó, tôi đã viết một blog về tham gia phân vùng khôn ngoan trong PostgreSQL. Trong blog đó, tôi đã nói về một kỹ thuật so khớp phân vùng nâng cao sẽ cho phép kết hợp phân vùng khôn ngoan được sử dụng trong nhiều trường hợp hơn. Trong blog này, chúng tôi sẽ thảo luận chi tiết về kỹ thuật này.

Tóm lại, kỹ thuật so khớp phân vùng cơ bản cho phép thực hiện phép nối giữa hai bảng được phân vùng bằng cách sử dụng kỹ thuật nối theo phân vùng nếu hai bảng được phân vùng có giới hạn phân vùng khớp chính xác, ví dụ:bảng phân vùng prt1 và prt2 được mô tả bên dưới

psql>\d+ prt1
... [output clipped]
Partition key: RANGE (a)
Partitions: prt1_p1 FOR VALUES FROM (0) TO (5000),
prt1_p2 FOR VALUES FROM (5000) TO (15000),
prt1_p3 FOR VALUES FROM (15000) TO (30000)

psql>\d+ prt2
... [ output clipped ]
Partition key: RANGE (b)
Partitions: prt2_p1 FOR VALUES FROM (0) TO (5000),
prt2_p2 FOR VALUES FROM (5000) TO (15000),
prt2_p3 FOR VALUES FROM (15000) TO (30000)

Một phép nối giữa prt1 và prt2 trên khóa phân vùng (a) của chúng được chia thành các phép nối giữa các phân vùng phù hợp của chúng, tức là prt1_p1 tham gia prt2_p1, prt1_p2 tham gia prt2_p2 và prt1_p3 tham gia prt2_p3. Kết quả của ba phép nối này với nhau tạo thành kết quả của phép nối giữa prt1 và prt2. Điều này có nhiều lợi thế như đã thảo luận trong blog trước của tôi. Tuy nhiên, kết hợp phân vùng cơ bản không thể nối hai bảng được phân vùng với các giới hạn phân vùng khác nhau. Trong ví dụ trên, nếu prt1 có thêm một phân vùng prt1_p4 CHO GIÁ TRỊ TỪ (30000) ĐẾN (50000), đối sánh phân vùng cơ bản sẽ không giúp chuyển đổi một phép nối giữa prt1 và prt2 thành một phép nối phân vùng vì chúng không có phân vùng khớp chính xác giới hạn.

Nhiều ứng dụng sử dụng phân vùng để tách biệt dữ liệu đã sử dụng tích cực và dữ liệu cũ, một kỹ thuật mà tôi đã thảo luận trong một blog khác của mình. Dữ liệu cũ cuối cùng sẽ bị loại bỏ bằng cách giảm các phân vùng. Các phân vùng mới được tạo để chứa dữ liệu mới. Một phép nối giữa hai bảng được phân vùng như vậy chủ yếu sẽ sử dụng phép nối theo phân vùng vì hầu hết thời gian chúng sẽ có các phân vùng phù hợp. Nhưng khi một phân vùng đang hoạt động được thêm vào một trong các bảng này hoặc một phân vùng cũ bị xóa, giới hạn phân vùng của chúng sẽ không khớp cho đến khi bảng khác cũng trải qua một thao tác tương tự. Trong khoảng thời gian đó, phép nối giữa hai bảng này sẽ không sử dụng phép nối phân vùng và có thể mất nhiều thời gian hơn bất thường để thực thi. Chúng tôi không muốn một phép nối truy cập vào cơ sở dữ liệu trong khoảng thời gian nhỏ này hoạt động kém vì nó không thể sử dụng phép nối theo phân vùng. Thuật toán so khớp phân vùng nâng cao giúp ích trong trường hợp này và các trường hợp phức tạp hơn khi giới hạn phân vùng không khớp chính xác.

Thuật toán so khớp phân vùng nâng cao

Kỹ thuật so khớp phân vùng nâng cao tìm các phân vùng phù hợp từ hai bảng được phân vùng ngay cả khi giới hạn phân vùng của chúng không khớp chính xác. Nó tìm các phân vùng phù hợp bằng cách so sánh các giới hạn từ cả hai bảng theo thứ tự được sắp xếp của chúng tương tự như thuật toán kết hợp hợp nhất. Bất kỳ hai phân vùng nào, một phân vùng từ mỗi bảng được phân vùng, có giới hạn khớp chính xác hoặc trùng lặp được coi là tham gia đối tác vì chúng có thể chứa các hàng tham gia. Tiếp tục với ví dụ trên, giả sử một phân vùng mới đang hoạt động prt2_p4 được thêm vào prt4. Các bảng được phân vùng bây giờ trông giống như sau:

psql>\d+ prt1
... [output clipped]
Partition key: RANGE (a)
Partitions: prt1_p1 FOR VALUES FROM (0) TO (5000),
prt1_p2 FOR VALUES FROM (5000) TO (15000),
prt1_p3 FOR VALUES FROM (15000) TO (30000)

psql>\d+ prt2
... [ output clipped ]
Partition key: RANGE (b)
Partitions: prt2_p1 FOR VALUES FROM (0) TO (5000),
prt2_p2 FOR VALUES FROM (5000) TO (15000),
prt2_p3 FOR VALUES FROM (15000) TO (30000),
prt2_p4 FOR VALUES FROM (30000) TO (50000)

Dễ dàng nhận thấy rằng giới hạn phân vùng của prt1_p1 và prt2_p1, prt1_p2 và prt2_p2 và prt1_p3 và prt2_p3 tương ứng khớp nhau. Nhưng không giống như đối sánh phân vùng cơ bản, đối sánh phân vùng nâng cao sẽ biết rằng prt2_p4 không có bất kỳ phân vùng phù hợp nào trong prt1. Nếu phép nối giữa prt1 và prt2 là phép nối INNER hoặc khi prt2 là quan hệ INNER trong phép nối, thì kết quả nối sẽ không có bất kỳ hàng nào từ prt2_p4. Được kích hoạt với thông tin chi tiết về các phân vùng phù hợp và phân vùng không khớp, cũng giống như việc chỉ dựa vào việc giới hạn phân vùng có khớp hay không, trình tối ưu hóa truy vấn có thể quyết định xem có sử dụng tham gia phân vùng hay không. Trong trường hợp này, nó sẽ chọn thực hiện phép nối dưới dạng phép nối giữa các phân vùng phù hợp, bỏ prt2_p4 sang một bên. Nhưng điều đó không giống như đối sánh phân vùng "nâng cao". Chúng ta hãy xem trường hợp phức tạp hơn một chút bằng cách sử dụng danh sách các bảng được phân vùng lần này:

psql>\d+ plt1
Partition key: LIST (c)
Partitions: plt1_p1 FOR VALUES IN ('0001', '0003'),
plt1_p2 FOR VALUES IN ('0004', '0006'),
plt1_p3 FOR VALUES IN ('0008', '0009')

psql>\d+ plt2
Partition key: LIST (c)
Partitions: plt2_p1 FOR VALUES IN ('0002', '0003'),
plt2_p2 FOR VALUES IN ('0004', '0006'),
plt2_p3 FOR VALUES IN ('0007', '0009')

Quan sát rằng có chính xác ba phân vùng trong cả hai mối quan hệ nhưng danh sách giá trị phân vùng khác nhau. Danh sách tương ứng với phân vùng plt1_p2 khớp chính xác với phân vùng plt2_p2. Ngoài ra, không có hai phân vùng, một phân vùng ở hai bên, có danh sách khớp chính xác. Thuật toán so khớp phân vùng nâng cao suy ra rằng plt1_p1 và plt2_p1 có danh sách chồng chéo và danh sách của chúng không trùng lặp với bất kỳ phân vùng nào khác từ mối quan hệ khác. Tương tự cho plt1_p3 và plt2_p3. Sau đó, trình tối ưu hóa truy vấn thấy rằng phép nối giữa plt1 và plt2 có thể được thực thi dưới dạng phép nối theo phân vùng bằng cách nối các phân vùng phù hợp, tức là plt1_p1 và plt2_p1, plt1_p2 và plt2_p2, và plt1_p3 và plt2_p3 tương ứng. Thuật toán có thể tìm thấy các phân vùng phù hợp trong các tập hợp danh sách giới hạn phân vùng phức tạp hơn cũng như các bảng được phân vùng theo phạm vi. Nhưng chúng tôi sẽ không bao gồm chúng vì mục đích ngắn gọn. Độc giả quan tâm và táo bạo hơn có thể xem cam kết. Nó cũng có nhiều tủ thử nghiệm, hiển thị các tình huống khác nhau trong đó thuật toán so khớp phân vùng nâng cao được sử dụng.

Hạn chế

Kết hợp bên ngoài với các phân vùng phù hợp bị thiếu ở phía bên trong

Các phép tham gia bên ngoài đặt ra một vấn đề cụ thể trong thế giới PostgreSQL. Hãy xem xét prt2 LEFT JOIN prt1, trong ví dụ trên, trong đó prt2 là một quan hệ OUTER. prt2_p4 không có đối tác tham gia trong prt1 và các hàng trong phân vùng đó phải là một phần của kết quả liên kết vì chúng thuộc về quan hệ ngoài. Trong PostgreSQL khi phía INNER của một phép nối trống, nó được biểu thị bằng một quan hệ "giả" không tạo ra hàng nào nhưng vẫn biết lược đồ của mối quan hệ đó. Thông thường, một quan hệ "giả" xuất hiện từ một quan hệ không giả sẽ không tạo ra bất kỳ hàng nào vì một số tối ưu hóa truy vấn như loại trừ ràng buộc. Trình tối ưu hóa truy vấn của PostgreSQL đánh dấu một mối quan hệ không phải giả như là giả và trình thực thi tiến hành bình thường khi thực thi một phép nối như vậy. Nhưng khi không có phân vùng bên trong phù hợp cho phân vùng bên ngoài, thì không có "thực thể hiện có" nào có thể được đánh dấu là "giả". Ví dụ, trong trường hợp này không có prt1_p4 nào có thể đại diện cho phân vùng giả bên trong tham gia prt2_p4 bên ngoài. Hiện tại, PostgreSQL không có cách nào để "tạo" các quan hệ "giả" như vậy trong quá trình lập kế hoạch. Do đó, trình tối ưu hóa truy vấn không sử dụng phép nối theo phân vùng trong trường hợp này.

Lý tưởng nhất là một phép nối với rỗng bên trong chỉ yêu cầu lược đồ của quan hệ bên trong chứ không phải toàn bộ quan hệ. Lược đồ này có thể được lấy từ chính bảng được phân vùng. Tất cả những gì nó cần là khả năng tạo ra hàng nối bằng cách sử dụng các cột từ một hàng ở phía bên ngoài được nối bằng các giá trị NULL cho các cột từ phía bên trong. Khi chúng ta có khả năng đó trong PostgreSQL, trình tối ưu hóa truy vấn sẽ có thể sử dụng kết hợp phân vùng khôn ngoan ngay cả trong những trường hợp này.

Hãy để tôi nhấn mạnh rằng các phép nối bên ngoài mà không có phân vùng nào bị thiếu trên phép nối bên trong sử dụng phép nối phân vùng khôn ngoan.

Nhiều phân vùng phù hợp

Khi các bảng được phân vùng sao cho nhiều phân vùng từ một bên khớp với một hoặc nhiều phân vùng ở bên kia, thì không thể sử dụng phép nối theo phân vùng vì không có cách nào tạo ra quan hệ "Nối" trong thời gian lập kế hoạch đại diện cho hai hoặc nhiều các vách ngăn với nhau. Hy vọng rằng một lúc nào đó chúng tôi cũng sẽ loại bỏ hạn chế đó và cho phép phép tham gia theo phân vùng cũng được sử dụng trong những trường hợp đó.

Các bảng được phân vùng băm

Giới hạn phân vùng của hai bảng được phân vùng băm sử dụng cùng một mô-đun luôn khớp. Khi mô-đun khác nhau, một hàng từ một phân vùng nhất định của một bảng có thể có các đối tác tham gia của nó trong nhiều phân vùng của bảng kia, do đó một phân vùng nhất định từ một bên khớp với nhiều phân vùng của bảng khác, do đó làm cho phép tham gia theo phân vùng không hiệu quả.

Khi thuật toán so khớp phân vùng nâng cao không tìm thấy các phân vùng phù hợp hoặc không thể sử dụng phép nối theo phân vùng vì những hạn chế trên, PostgreSQL sẽ quay trở lại tham gia các bảng được phân vùng như các bảng thông thường.

Thời gian đối sánh phân vùng nâng cao

Simon đã đưa ra một điểm thú vị khi bình luận về tính năng này. Các phân vùng của bảng được phân vùng không thay đổi thường xuyên vì vậy kết quả của việc đối sánh phân vùng nâng cao sẽ được giữ nguyên trong thời gian dài hơn. Việc tính toán nó mỗi khi một truy vấn liên quan đến các bảng này được thực thi là không cần thiết. Thay vào đó, chúng ta có thể lưu tập hợp các phân vùng phù hợp trong một số danh mục và làm mới nó mỗi khi các phân vùng thay đổi. Đó là một số công việc nhưng đáng để dành thời gian để khớp phân vùng cho mọi truy vấn.

Ngay cả với tất cả những hạn chế này, những gì chúng ta có ngày hôm nay là một giải pháp rất hữu ích phục vụ hầu hết các trường hợp thực tế. Không cần phải nói rằng tính năng này hoạt động liền mạch với FDW tham gia đẩy xuống cải thiện khả năng sharding mà PostgreSQL đã có!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. cài đặt postgres, khởi tạo cụm cơ sở dữ liệu không thành công (Postgresql Phiên bản 9.4.4)

  2. Cách tạo và xóa cơ sở dữ liệu và bảng trong PostgreSQL

  3. Nâng cấp PostgreSQL 11 lên PostgreSQL 13 với TimescaleDB và PostGIS trong Linux bằng pg_upgrade

  4. PostgreSql:Json Array to Rows bằng cách sử dụng liên kết bên

  5. Tổng quan về các nút kế hoạch phụ trợ khác nhau trong PostgreSQL