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

unaccent () ngăn việc sử dụng chỉ mục trong Postgres

Biến thể IMMUTABLE của unaccent()

Để làm rõ thông tin sai lệch trong câu trả lời hiện được chấp nhận, không chính xác :
Chỉ mục biểu thức chỉ cho phép IMMUTABLE các hàm (vì lý do rõ ràng) và unaccent() chỉ là STABLE . giải pháp bạn đã đề xuất trong nhận xét cũng có vấn đề. Giải thích chi tiết và một giải pháp thích hợp vì điều đó :

Tùy thuộc vào nội dung của thẻ tags->name có thể hữu ích khi thêm unaccent() với chỉ mục biểu thức, nhưng điều đó trực giao với câu hỏi tại sao chỉ mục không được sử dụng:

Vấn đề / giải pháp thực tế

Toán tử LIKE trong truy vấn của bạn là sai một cách tinh vi (rất có thể). Bạn không muốn diễn giải 'Weststrasse' dưới dạng mẫu tìm kiếm, bạn muốn đối sánh chuỗi (chuẩn hóa) như hiện tại. Thay thế bằng = và bạn sẽ thấy bản quét chỉ mục (bitmap) với chỉ mục hiện tại của bạn, không đều biến động hàm của unaccent() :

SELECT * FROM germany.ways
WHERE lower(tags->'name') = lower(unaccent('unaccent','Weststrasse'))

Tại sao?

Toán hạng bên phải của LIKE là một mẫu . Postgres không thể sử dụng chỉ mục btree thuần túy để đối sánh mẫu ( áp dụng ngoại lệ ). Một LIKE với một chuỗi thuần túy dưới dạng mẫu (không có ký tự đặc biệt) có thể được tối ưu hóa với việc kiểm tra tính bình đẳng trên chỉ mục btree. Nhưng nếu có các ký tự đặc biệt trong chuỗi, this chỉ mục đã hết.

Nếu có IMMUTABLE chức năng ở bên phải của LIKE , nó có thể được đánh giá ngay lập tức và việc tối ưu hóa đã nói vẫn có thể thực hiện được. Theo tài liệu về Danh mục biến động chức năng :

Điều này cũng không thể xảy ra với một hàm ít biến động hơn (STABLE hoặc VOLATILE ). Đó là lý do tại sao "giải pháp" giả mạo IMMUTABLE unaccent() của bạn có vẻ hiệu quả, nhưng nó thực sự đánh son lên một con lợn.

Để nhắc lại:

  • Nếu bạn muốn làm việc với LIKE và các mẫu, hãy sử dụng chỉ mục bát quái .
  • Nếu bạn không muốn làm việc với LIKE và các mẫu, hãy sử dụng toán tử bình đẳ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. Các cơ sở dữ liệu ngoài Postgres có các tính năng tương đương với các trình bao bọc dữ liệu nước ngoài không?

  2. Làm thế nào để trả về các loại bảng tùy chỉnh từ Npgsql và các thủ tục được lưu trữ?

  3. PHPpgAdmin:Cách xóa các hàng mà không cần sử dụng SQL

  4. Nhận kết quả từ hàm Postgresql có giá trị trong bảng với JOOQ

  5. Postgis SQL cho những người hàng xóm gần nhất