PostgreSQL 関数と関数内の関数呼び出しのパフォーマンスを改善しようとしています。
私たちのアプリケーションでは、PostgreSQL (9.6) クエリは完全に関数に基づいています。たとえば、多くの「アイテム」を取得するには、次のようなコードを使用できます。
CREATE OR REPLACE FUNCTION public.item_read_one(
"itemID" integer)
RETURNS jsonb AS
$BODY$
DECLARE
outputvariable jsonb;
BEGIN
SELECT row_to_json (my_subquery) FROM (
SELECT
id,
"simpleField1",
"simpleField2",
item_status(id,"crucialField") AS status
FROM item_table
WHERE id = $1 AND deleted IS NOT TRUE)
AS my_subquery into outputvariable ;
RETURN outputvariable;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public.item_read_one(integer)
OWNER TO some_user;
ご覧のとおり、内部SELECT
には、いくつかの単純なフィールドのほかに、別の関数呼び出しがあります。これらの内部関数は通常 plv8 ベースであり、データベース クエリを含む多くの JavaScript ロジックが含まれています。例は次のようになります。
CREATE OR REPLACE FUNCTION public.item_status(
"itemID" integer,
"crucialField" text)
RETURNS jsonb AS
$BODY$
var returnStatus = {};
var myVariable;
if(crucialField == 'foo') {
myVariable = plv8.execute('SELECT something FROM other_table WHERE "itemID" = $1',[itemID]);
}
else if(crucialField == 'sweetKitten') {
myVariable = plv8.execute('SELECT "somethingElse" FROM kitten WHERE "itemID" = $1',[itemID]);
}
/*
A lot more JavaScript logic here. But you get the idea, I hope.
*/
return returnStatus;
$BODY$
LANGUAGE plv8 IMMUTABLE
COST 100;
ALTER FUNCTION public.item_status(integer, text)
OWNER TO some_user;
この設計が理にかなっているのかという問題は別として、問題は次のとおりです。パフォーマンスを向上させる方法は?
item_status のような関数によって返されるデータは非常に安定しているため、インデックスに入れることは理にかなっていますが、方法はわかりません。
使用する PostgreSQL のバージョンは 9.6 です。