大いに期待しています このアプローチでより速い結果:
1。
連結された値を保持する1つの列を持つGiSTインデックスを作成します:
CREATE INDEX users_search_idx ON auth_user
USING gist((username || ' ' || first_name || ' ' || last_name) gist_trgm_ops);
これは、3つの列すべてがNOT NULL
で定義されていることを前提としています。 (指定しませんでした)。それ以外の場合は、さらに多くのことを行う必要があります。
concat_ws()
で単純化してみませんか ?
2。
適切な
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;
WHERE
の式 およびORDER BY
インデックス式と一致する必要があります!
特にORDER BY rank
(あなたが持っていたように)小さなLIMIT
では常にパフォーマンスが低下します インデックスを直接使用できないため、修飾行のはるかに大きなプールから選択します。rank
の背後にある洗練された式 すべてについて計算する必要があります 適格な行の場合、最適な一致の小さな選択を返す前に、すべてを並べ替える必要があります。これははるかに高価です 残りの部分を見なくても、インデックスから直接最良の結果を選択できる真の最近傍クエリよりも。
row_number()
空のウィンドウ定義では、ORDER BY
によって生成された順序が反映されます。 同じSELECT
の 。
関連する回答:
アイテムは3.
、あなたが参照した質問に答えを追加しました。それはそれを説明するはずです: