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

Chỉ mục để tìm một phần tử trong một mảng JSON

jsonb trong Postgres 9.4+

Kiểu dữ liệu JSON nhị phân jsonb cải thiện phần lớn các tùy chọn chỉ mục. Bây giờ bạn có thể có chỉ mục GIN trên jsonb mảng trực tiếp:

CREATE TABLE tracks (id serial, artists jsonb);  -- !
CREATE INDEX tracks_artists_gin_idx ON tracks USING gin (artists);

Không cần hàm để chuyển đổi mảng. Điều này sẽ hỗ trợ một truy vấn:

SELECT * FROM tracks WHERE artists @> '[{"name": "The Dirty Heads"}]';

@> jsonb toán tử "chứa", có thể sử dụng chỉ mục GIN. (Không dành cho json , chỉ jsonb !)

Hoặc bạn sử dụng lớp toán tử GIN chuyên biệt hơn, không phải mặc định jsonb_path_ops cho chỉ mục:

CREATE INDEX tracks_artists_gin_idx ON tracks
USING  gin (artists jsonb_path_ops);  -- !

Cùng một truy vấn.

Hiện tại jsonb_path_ops chỉ hỗ trợ @> nhà điều hành. Nhưng nó thường nhỏ hơn và nhanh hơn nhiều. Có nhiều tùy chọn chỉ mục hơn, chi tiết trong hướng dẫn sử dụng .

Nếu cột artists chỉ giữ các tên được hiển thị trong ví dụ, sẽ hiệu quả hơn nếu chỉ lưu trữ các giá trị dưới dạng văn bản JSON nguyên thủy khóa dư thừa có thể là tên cột.

Lưu ý sự khác biệt giữa các đối tượng JSON và các kiểu nguyên thủy:

  • Sử dụng các chỉ mục trong mảng json trong PostgreSQL
CREATE TABLE tracks (id serial, artistnames jsonb);
INSERT INTO tracks  VALUES (2, '["The Dirty Heads", "Louis Richards"]');

CREATE INDEX tracks_artistnames_gin_idx ON tracks USING gin (artistnames);

Truy vấn:

SELECT * FROM tracks WHERE artistnames ? 'The Dirty Heads';

? không hoạt động cho đối tượng giá trị , chỉ phím phần tử mảng .

Hoặc:

CREATE INDEX tracks_artistnames_gin_idx ON tracks
USING  gin (artistnames jsonb_path_ops);

Truy vấn:

SELECT * FROM tracks WHERE artistnames @> '"The Dirty Heads"'::jsonb;

Hiệu quả hơn nếu tên có tính trùng lặp cao.

json trong Postgres 9.3+

Điều này sẽ hoạt động với IMMUTABLE chức năng :

CREATE OR REPLACE FUNCTION json2arr(_j json, _key text)
  RETURNS text[] LANGUAGE sql IMMUTABLE AS
'SELECT ARRAY(SELECT elem->>_key FROM json_array_elements(_j) elem)';

Tạo chỉ mục chức năng này :

CREATE INDEX tracks_artists_gin_idx ON tracks
USING  gin (json2arr(artists, 'name'));

Và sử dụng truy vấn như thế này. Biểu thức trong WHERE mệnh đề phải khớp với mệnh đề trong chỉ mục:

SELECT * FROM tracks
WHERE  '{"The Dirty Heads"}'::text[] <@ (json2arr(artists, 'name'));

Cập nhật thông tin phản hồi trong nhận xét. Chúng tôi cần sử dụng toán tử mảng để hỗ trợ chỉ mục GIN.
Toán tử "được chứa bởi" <@ trong trường hợp này.

Ghi chú về sự biến động của chức năng

Bạn có thể khai báo hàm của mình IMMUTABLE ngay cả khi json_array_elements() không phải không.
Hầu hết JSON các chức năng được sử dụng để chỉ STABLE , không phải IMMUTABLE . Đã có một cuộc thảo luận về danh sách tin tặc để thay đổi điều đó. Hầu hết là IMMUTABLE Hiện nay. Kiểm tra với:

SELECT p.proname, p.provolatile
FROM   pg_proc p
JOIN   pg_namespace n ON n.oid = p.pronamespace
WHERE  n.nspname = 'pg_catalog'
AND    p.proname ~~* '%json%';

Chỉ mục chức năng chỉ hoạt động với IMMUTABLE các chức năng.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. pip cài đặt không thành công với / usr / bin / clang:Không có tệp hoặc thư mục như vậy

  2. Chọn kiểu dữ liệu của trường trong postgres

  3. XMLTABLE trong PostgreSQL

  4. 3 cách liệt kê tất cả các thủ tục được lưu trữ tham chiếu đến một bảng trong PostgreSQL

  5. Cài đặt Odoo trên Mac Không thể Thực thi Lệnh LESSC