Công cụ lập kế hoạch truy vấn PostgreSQL thông minh, nhưng không phải là AI. Để làm cho nó sử dụng chỉ mục trên một biểu thức sử dụng cùng một dạng biểu thức trong truy vấn.
Với một chỉ mục như thế này:
CREATE INDEX t_a_lower_idx ON t (lower(substring(a, 1, 4)));
Hoặc đơn giản hơn trong PostgreSQL 9.1:
CREATE INDEX t_a_lower_idx ON t (lower(left(a, 4)));
Sử dụng truy vấn này:
SELECT * FROM t WHERE lower(left(a, 4)) = 'abcd';
Tương đương 100% về mặt chức năng với:
SELECT * FROM t WHERE lower(a) LIKE 'abcd%'
Hoặc:
SELECT * FROM t WHERE a ILIKE 'abcd%'
Nhưng không :
SELECT * FROM t WHERE a LIKE 'abcd%'
Đây là một truy vấn khác về mặt chức năng và bạn cần một khác chỉ mục:
CREATE INDEX t_a_idx ON t (substring(a, 1, 4));
Hoặc đơn giản hơn với PostgreSQL 9.1:
CREATE INDEX t_a_idx ON t (left(a, 4));
Và sử dụng truy vấn này:
SELECT * FROM t WHERE left(a, 4) = 'abcd';
Các cụm từ tìm kiếm cố định bên trái có độ dài thay đổi
Trường hợp không nhạy cảm. Chỉ mục:
Chỉnh sửa :Gần như đã quên:Nếu bạn chạy db của mình bằng bất kỳ ngôn ngữ nào khác ngoài 'C' mặc định, bạn cần chỉ định lớp toán tử một cách rõ ràng
- text_pattern_ops
trong ví dụ của tôi:
CREATE INDEX t_a_lower_idx
ON t (lower(left(a, <insert_max_length>)) text_pattern_ops);
Truy vấn:
SELECT * FROM t WHERE lower(left(a, <insert_max_length>)) ~~ 'abcdef%';
Có thể sử dụng chỉ mục và gần như nhanh như biến thể có độ dài cố định.
Bạn có thể quan tâm đến bài đăng này trên dba.SE với nhiều chi tiết hơn về đối sánh mẫu
, đặc biệt là phần cuối cùng về các toán tử ~>=~
và ~<~
.