Expression index (index trên biểu thức) đánh index lên kết quả của một biểu thức thay vì giá trị cột thô.
Nó giải quyết đúng tình huống mà điều kiện bắt buộc phải bọc cột trong hàm.
CREATE INDEX idx_users_email_lower ON users (lower(email));
-- planner matches this query to the index above
SELECT * FROM users WHERE lower(email) = lower($1);Quy tắc khớp: biểu thức trong WHERE phải trùng khớp với biểu thức lúc CREATE INDEX. Viết WHERE upper(email) = ... sẽ không dùng được index trên lower(email).
Ràng buộc: hàm dùng trong expression index phải là IMMUTABLE — cùng đầu vào luôn cho cùng đầu ra. Vì vậy now() hay to_char(ts, ...) phụ thuộc timezone bị từ chối; muốn index theo ngày của một timestamptz thì phải ép timezone tường minh, ví dụ ((created_at AT TIME ZONE 'UTC')::date).
Chi phí: biểu thức được tính lại mỗi lần INSERT/UPDATE nên ghi đắt hơn index thường. Nếu cùng một chuẩn hoá được dùng ở khắp nơi, cân nhắc lưu hẳn một generated column rồi đánh index bình thường lên cột đó — dễ đọc và dễ tái sử dụng hơn.
Một ứng dụng phổ biến khác là ép duy nhất không phân biệt hoa thường: CREATE UNIQUE INDEX ... ON users (lower(email)).