我有一个函数,它使用传递给它的变量执行动态查询。
我定义了表达式索引,但它们没有被使用。平均查询大约需要7秒钟。如果我这样做:
SET enable_seqscan=f;
同样的查询只需1秒钟。如何让Postgres使用索引?
这是我的功能:
--Usage: select * from scored_search('hinton', 0.5, 1.0, 10000);
CREATE OR REPLACE FUNCTION scored_search(
vn character varying(500), tn real, wn real, lim integer
) RETURNS SETOF contact_index_with_score AS
$func$
DECLARE
nlim integer := lim/4;
BEGIN
RETURN QUERY EXECUTE
'SELECT *,
(CASE gn > $2 WHEN true THEN gn ELSE 0 END) * $3
AS score
FROM (
SELECT *,
/* Word sim parameters ordered so name token can match multi-token name */
greatest(multi_word_similarity(coalesce($1,''''), coalesce(contact_name1,'''')),
multi_word_similarity(coalesce($1,''''), coalesce(contact_name2,'''')),
multi_word_similarity(coalesce($1,''''), coalesce(contact_name3,'''')),
multi_word_similarity(coalesce($1,''''), coalesce(contact_name4,'''')),
multi_word_similarity(coalesce($1,''''), coalesce(contact_name5,''''))) AS gn
FROM (
(SELECT * FROM contact_search_index WHERE $1 <%
normalize_string(coalesce(contact_name1,'''') || '' '' ||
coalesce(contact_name2,'''') || '' '' ||
coalesce(contact_name3,'''') || '' '' ||
coalesce(contact_name4,'''') || '' '' ||
coalesce(contact_name5,'''')) COLLATE "default" LIMIT $13)
) AS filtered_contact_index
) AS max_similarities
ORDER BY score DESC'
USING
vn, tn, wn, nlim;
END
$func$
LANGUAGE plpgsql;
这是我的索引定义:
CREATE INDEX contact_search_name_trgm_idx on contact_search_index
USING GIN((
normalize_string(coalesce(contact_name1, '') || ' ' ||
coalesce(contact_name2, '') || ' ' ||
coalesce(contact_name3, '') || ' ' ||
coalesce(contact_name4, '') || ' ' ||
coalesce(contact_name5, ''))
) COLLATE "default" gin_trgm_ops);