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

Tối ưu hóa truy vấn tương tự postgres (pg_trgm + gin index)

Tôi mong đợi nhiều kết quả nhanh hơn với cách tiếp cận này:

1.

Tạo chỉ mục GiST với 1 cột chứa các giá trị được nối:

CREATE INDEX users_search_idx ON auth_user
USING gist((username || ' ' || first_name || ' ' || last_name) gist_trgm_ops);

Điều này giả định rằng tất cả 3 cột được xác định NOT NULL (bạn không nói rõ). Nếu không, bạn cần phải làm nhiều việc hơn.
Tại sao không đơn giản hóa với concat_ws() ?

2.

Sử dụng một thích hợp truy vấn, khớp với chỉ mục trên:

SELECT username, email, first_name, last_name
     , similarity(username  , $1) AS s_username
     , similarity(first_name, $1) AS s_first_name
     , similarity(last_name , $1) AS s_last_name
     , row_number() OVER () AS rank  -- greatest similarity first
FROM   auth_user
WHERE     (username || ' ' || first_name || ' ' || last_name) %   $1  -- !!
ORDER  BY (username || ' ' || first_name || ' ' || last_name) <-> $1  -- !!
LIMIT  $2;

Biểu thức trong WHEREORDER BY phải khớp với biểu thức chỉ mục!

Cụ thể là ORDER BY rank (giống như bạn đã có) sẽ luôn hoạt động kém trong một LIMIT nhỏ chọn từ một nhóm lớn hơn nhiều các hàng đủ điều kiện, vì nó không thể sử dụng chỉ mục trực tiếp:Biểu thức phức tạp đằng sau rank phải được tính toán cho mọi hàng loại, sau đó tất cả phải được sắp xếp trước khi có thể trả lại lựa chọn nhỏ các trận đấu tốt nhất. Cái này rất nhiều, đắt hơn nhiều hơn là một truy vấn hàng xóm gần nhất thực sự có thể chọn trực tiếp kết quả tốt nhất từ ​​chỉ mục mà không cần xem xét phần còn lại.

row_number() với định nghĩa cửa sổ trống chỉ phản ánh thứ tự do ORDER BY tạo ra của cùng một SELECT .

Các câu trả lời liên quan:

Đối với mặt hàng của bạn 3. , Tôi đã thêm một câu trả lời cho câu hỏi mà bạn đã tham khảo, điều đó sẽ giải thích nó:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bảng in không vừa với kích thước trang

  2. Trả lại một truy vấn từ một hàm?

  3. pg_dump với người dùng không có superradmin và các đối tượng lớn

  4. Sequelize upsert () không bao giờ cập nhật và chỉ chèn

  5. (Python) cài đặt psycopg2