有一张表格:
create table individual_profile_identity
(
normalized_document_number varchar,
normalized_name varchar,
birth_date date
);
其中有一个索引:
create index individual_profile_identity_name_birth_dt_doc_idx
on individual_profile_identity (
normalized_name varchar_pattern_ops,
birth_date,
normalized_document_number
);
有一个函数可以规范化document_number
和name
字段:
create function rf_normalize_name(par_name character varying) returns character varying
language plpgsql
as
$$
BEGIN
RETURN nullif(upper(translate(par_name, 'A !@#$%^&*()_-+={}[]:;"''<>,.?/|\`~', 'A')), '0');
END
$$;
查询:
explain
select *
from individual_profile_identity
where normalized_name=rf_normalize_name('John Donne')
and birth_date='2000-01-01'
and normalized_document_number=rf_normalize_name('1234 567890');
计划:
Index Scan using individual_profile_identity_name_birth_dt_doc_idx on individual_profile_identity (cost=0.41..1935.18 rows=1 width=173)
Index Cond: (birth_date = '2000-01-01'::date)
Filter: (((normalized_name)::text = (rf_normalize_name('John Donne'::character varying))::text) AND ((normalized_document_number)::text = (rf_normalize_name('1234 567890'::character varying))::text))
正如您所看到的,它使用索引,但仅限于birth_date
其中:
Index Cond: (birth_date = '2000-01-01'::date)
我完全不明白为什么 postgres 不先运行rf_normalize_name
函数,然后再将索引应用于所有 3 个字段
有人可以解释一下这种行为吗?