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

Chỉ mục GIN trên cột smallint [] không được sử dụng hoặc toán tử lỗi không phải là duy nhất

Giải pháp

Có lẽ nhất là giải pháp là để đủ điều kiện cho toán tử lược đồ:

SELECT *
FROM   test
WHERE  tagged OPERATOR([email protected]>) '{11}'::int2[]
ORDER  BY id
LIMIT  100;

Tại sao?

Đó là vấn đề về cách giải quyết của nhà điều hành (kết hợp với độ phân giải kiểu và ngữ cảnh truyền).

Trong Postgres tiêu chuẩn, chỉ có một toán tử ứng cử viên duy nhất anyarray @> anyarray , đó là cái bạn muốn.

Thiết lập của bạn sẽ hoạt động tốt nếu bạn chưa cài đặt phần xâm nhập mô-đun bổ sung (giả định của tôi), cung cấp một toán tử khác cho integer[] @> integer[] .

Do đó, một giải pháp khác sẽ là sử dụng integer[] thay vào đó và có chỉ mục GIN với gin__int_ops lớp toán tử. Hoặc thử (mặc định cho intarray) gist__int_ops mục lục. Có thể nhanh hơn, nhưng cả hai đều không cho phép giá trị NULL.
Hoặc bạn có thể đổi tên intarray toán tử @> để phân biệt. (Tôi sẽ không làm điều đó. Các vấn đề nâng cấp và tính di động xảy ra sau đó.)

Đối với các biểu thức liên quan đến ít nhất một toán hạng của kiểu integer[] , Postgres biết toán tử nào cần chọn:toán tử intarray. Nhưng sau đó chỉ mục không áp dụng được , bởi vì toán tử intarray chỉ hoạt động trên integer (int4 ) không phải int2 . Và các chỉ mục được ràng buộc chặt chẽ với các toán tử:

  • PostgreSQL có thể lập chỉ mục các cột mảng không?
  • Hành vi của PostgreSQL khi có hai loại chỉ mục khác nhau trên cùng một cột

Nhưng đối với int2[] @> int2[] , Postgres không thể quyết định nhà điều hành tốt nhất. Cả hai đều có vẻ áp dụng như nhau. Vì toán tử mặc định được cung cấp trong pg_catalog lược đồ và toán tử intarray được cung cấp trong public lược đồ (theo mặc định - hoặc bất cứ nơi nào bạn cài đặt tiện ích mở rộng), bạn có thể giúp giải quyết vấn đề hóc búa bằng cách định tính toán tử bằng lược đồ với OPERATOR() xây dựng. Có liên quan:

  • So sánh các mảng cho bằng nhau, bỏ qua thứ tự của các phần tử

Thông báo lỗi bạn nhận được là một chút sai lầm. Nhưng nếu bạn nhìn kỹ, có một HINT đã thêm dòng gợi ý (tada!) đúng hướng:

ERROR:  operator is not unique: smallint[] @> smallint[]
LINE 1: SELECT NULL::int2[] @> NULL::int2[]
                            ^
HINT:  Could not choose a best candidate operator. You might need to add explicit type casts.

Bạn có thể điều tra các ứng cử viên nhà điều hành hiện tại cho @> với:

SELECT o.oid, *, oprleft::regtype, oprright::regtype, n.nspname
FROM   pg_operator o
JOIN   pg_namespace n ON n.oid = o.oprnamespace
WHERE  oprname = '@>';

Một giải pháp thay thế khác là tạm thời (!) Đặt một đường dẫn tìm kiếm khác, do đó chỉ tìm thấy toán tử mong muốn. Trong cùng một giao dịch:

SET LOCAL search_path = pg_catalog;
SELECT ...

Nhưng sau đó bạn phải đủ điều kiện lược đồ cho tất cả các bảng trong truy vấn.

Về bối cảnh diễn viên:

  • Tạo chuỗi ngày - sử dụng loại ngày làm đầu vào

Bạn có thể thay đổi castcontext trong tổng số int2 -> int4 . Nhưng tôi khuyên bạn nên chống lại nó. Quá nhiều tác dụng phụ có thể xảy ra:

  • Có cách nào để truyền kiểu dữ liệu postgresql 9.3 để nó chỉ có thể ảnh hưởng đến một phía



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Yêu cầu cung cấp giấy tờ cho PGDay.IT 2011 đã được gia hạn

  2. Sự khác biệt giữa LIKE và ~ trong Postgres

  3. Làm thế nào để chuyển đổi cơ sở dữ liệu postgres sang sqlite

  4. Đặc quyền và bảo mật của PostgreSQL - Khóa giản đồ công khai

  5. Tạo bảng ở chế độ một người dùng trong postgres