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

Tối ưu hóa GROUP BY + COUNT DISTINCT trên cột jsonb chưa được thiết lập

Giả sử id không chỉ UNIQUE - như được thực thi bởi UNIQUE INDEX của bạn - but also NOT NULL . (Cái đó bị thiếu trong định nghĩa bảng của bạn.)

SELECT meta_split.key, meta_split.value, count(*)
FROM   voc_cc348779bdc84f8aab483f662a798a6a v
CROSS  JOIN LATERAL jsonb_each(v.meta) AS meta_split
GROUP  BY meta_split.key, meta_split.value;

Tương đương ngắn hơn:

SELECT meta_split.key, meta_split.value, count(*)
FROM   voc_cc348779bdc84f8aab483f662a798a6a v, jsonb_each(v.meta) AS meta_split
GROUP  BY 1, 2;

LEFT [OUTER] JOIN bị nhiễu vì kiểm tra sau WHERE meta_split.value IS NOT NULL buộc một INNER JOIN dù sao. Sử dụng CROSS JOIN thay vào đó.

Ngoài ra, vì jsonb không cho phép các khóa trùng lặp ở cùng một cấp (nghĩa là cùng một id chỉ có thể bật lên một lần per (key, value) ), DISTINCT chỉ là tiếng ồn đắt tiền. count(v.id) cũng rẻ hơn. Và count(*) tương đương và rẻ hơn - giả sử idNOT NULL như đã nêu ở trên cùng.

count(*) có một triển khai riêng biệt và nhanh hơn một chút so với count(<value>) . Nó khác một chút so với count(v.*) . Nó đếm tất cả các hàng, không có vấn đề gì. Trong khi biểu mẫu khác không tính NULL giá trị.

Đó là, miễn là id không thể là NULL - như đã nêu ở trên. id thực sự phải là PRIMARY KEY , vẫn được triển khai với chỉ mục B-tree duy nhất trong nội bộ và tất cả các cột - chỉ id đây - là NOT NULL ngầm hiểu. Hoặc ít nhất NOT NULL . UNIQUE INDEX không đủ điều kiện thay thế, nó vẫn cho phép NULL các giá trị không được coi là bằng nhau và được phép nhiều lần. Xem:

Ngoài ra, các chỉ mục không được sử dụng ở đây, vì tất cả các hàng phải được đọc. Vì vậy, điều này sẽ không bao giờ là rất rẻ. Nhưng 62k hàng không phải là số lượng hàng làm tê liệt theo bất kỳ phương tiện nào - trừ khi bạn có số lượng khóa lớn trong jsonb cột.

Các tùy chọn còn lại để tăng tốc:

  1. Bình thường hóa thiết kế của bạn. Unnesting tài liệu JSON không miễn phí.

  2. Duy trì một cái nhìn cụ thể hóa. Tính khả thi và chi phí phụ thuộc nhiều vào cách viết của bạn.

Đó là nơi các chỉ mục có thể đóng một vai trò trở lại ...




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgresql và jsonb - chèn khóa / giá trị vào mảng nhiều cấp

  2. Cách so sánh hai lược đồ trong PostgreSQL

  3. Thêm một cột làm khóa ngoại thì cột LỖI được tham chiếu trong ràng buộc khóa ngoại không tồn tại

  4. Để có kiểu boolean trong Postgres cho PHP

  5. Nhập Java trong JDBC sang Postgres ltree