このトピックでは、ユーザー定義関数 (UDF) について説明します。
仕組み
UDFは、作成後にメタセンターに保持されます。 UDFを計算ノードにロードして実行できます。 SQL関連の実行ロジックがSQLエンジンに送信されて実行され、実行結果が返されます。 制御フローに関連するような他のロジックは、PLエンジンにおいて実行される。
UDFは、実行される前にランタイム機能管理センターに登録されます。 1つのクエリのメモリサイズは、実行中に厳密に制限されます。
関数プッシュダウン
PolarDB-Xは、SQL data ACCESSフィールドをチェックして、UDFをデータノードに登録する必要があるかどうかを判断します。 SQL DATA ACCESSフィールドがno sqlに設定されている場合にのみ、UDFはデータノードにも登録されます。 データノードにUDFを登録した後、UDFをプッシュダウンできます。
MySQLとの互換性を維持するために、PolarDB-XはUDFをMySQLライブラリに登録します。
関数のプッシュダウンとスケーリング
スケーリング後、pushdown udf
ステートメントを実行して、新しいDNでプッシュダウンできるudfを登録できます。
MySQLとの違い
UDFではデータクエリ言語 (DQL) 操作のみを実行できますが、データ操作言語 (DML) またはデータ定義言語 (DDL) 操作は実行できません。
MySQLでは、関数はデータベースレベルで保存されます。 PolarDB-Xでは、UDFはインスタンスレベルで保存されます。
UDFのプッシュダウンロジックが関与しているため、SQL DATA ACCESSフィールドは変更できません。
注意事項
UDFは、PolarDB-X 5.4.16以降のインスタンスでのみサポートされます。
構文
UDFの作成
作成
[DEFINER=ユーザー]
FUNCTION sp_name ([func_parameter[,...]])
リターンタイプ
[特性...] routine_body
func_parameter:
param_nameタイプ
特性:
コメント '文字列'
| 言語SQL
| [NOT] 決定的
| {SQLを含む | SQLなし | SQLデータを読む | SQLデータの修正}
| SQLセキュリティ {DEFINER | INVOKER}
routione_body:
有効なSQLルーチンステートメント
例
CREATE FUNCTION my_mul(x int, y int)
リターンint
言語SQL
決定的
コメント '私の乗算機能'
戻るx * y * 31;
UDFの呼び出し
UDFは、一般的な組み込み関数と同じ方法で呼び出されます。
UDFの削除
ドロップ機能 [存在する場合] 機能名;
UDFの変更
ALTER FUNCTION func_name [特性...]
特性: {
コメント '文字列'
| 言語SQL
| SQLセキュリティ {DEFINER | INVOKER}
}
すべてのUDFを表示
SELECT * FROM information_schema.Routine_TYPE='FUNCTION';
指定されたUDFの表示
SHOW FUNCTION STATUS [LIKE 'pattern' | WHERE expr]
SHOW CREATE FUNCTION Function name;
SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME = 'Function name';
プッシュダウンされたUDFの表示
SELECT * FROM information_schema.pushed_function;
実行中のUDFのキャンセル
KILLステートメントを実行して、実行中のクエリを終了できます。
kill {query | connection} connection_id;
UDFのキャッシュ管理
カスタム関数のすべてのメタデータ (カスタム関数が存在するかどうか) は、常にキャッシュに格納されます。 ただし、関数本体は必要な場合にのみロードされます。
キャッシュされたUDFの表示
information_schema.function_cacheから * を選択します。
キャッシュサイズの表示
information_schema.function_cache_capacityから * を選択します。
キャッシュサイズの設定
resize関数キャッシュnum;
キャッシュのクリア
クリア関数キャッシュ。
UDFのリロード
リロード関数;
例
# UDFを作成します。
CREATE FUNCTION my_mul(x int, y int)
リターンint
言語SQL
DETERMINISTIC
コメント '私の乗算機能'
戻るx * y * 31;
# この時点ではUDFは呼び出されません。 ただし、関数はすでにキャッシュに存在します。
# キャッシュサイズは0で、UDFがロードされていないことを示します。
information_schema.function_cacheから * を選択します。+ -------------------- -------------- --------- +
| ID | 関数 | サイズ |
+ -------------------- -------------- --------- +
| xx.xx.xx.xx:3000 | mysql.my_mul | 0 |
| yy.yy.yy.yy:3100 | mysql.my_mul | 0 |
+ -------------------- -------------- --------- +
# UDFを呼び出します。
my_mul(2,2) を選択します。+ -------------
| my_mul(2, 2) |
+ -------------
| 124 |
+ -------------
# UDFがロードされたことを示す関連ビューを確認します。
information_schema.function_cacheから * を選択します。+ -------------------- -------------- --------- +
| ID | 関数 | サイズ |
+ -------------------- -------------- --------- +
| xx.xx.xx.xx:3000 | mysql.my_mul | 0 |
| yy.yy.yy.yy:3100 | mysql.my_mul | 79 |
+ -------------------- -------------- --------- +
information_schema.function_cache_capacityから * を選択します。+ -------------------- ---------- ----------------- +
| ID | USED_SIZE | TOTAL_SIZE |
+ -------------------- ---------- ----------------- +
| xx.xx.xx.xx:3000 | 0 | 15139759718 |
| yy.yy.yy.yy:3100 | 79 | 15139759718 |
+ -------------------- ---------- ----------------- +
# UDFをリロードすると、キャッシュがリセットされます。
リロード関数;
# 関連するビューを確認します。これは、キャッシュがリセットされたことを示します。
information_schema.function_cacheから * を選択します。+ -------------------- -------------- --------- +
| ID | 関数 | サイズ |
+ -------------------- -------------- --------- +
| xx.xx.xx.xx:3000 | mysql.my_mul | 0 |
| yy.yy.yy.yy:3100 | mysql.my_mul | 0 |
+ -------------------- -------------- --------- +
UDFのリソース管理
メモリの管理
UDFの実行中、メモリは主にカーソルをキャッシュするために使用されます。 したがって、PolarDB-Xでは、PL_CURSOR_MEMORY_LIMITおよびPL_MEMORY_LIMITパラメーターを使用して、単一のカーソルで使用できる最大メモリとUDFで使用できる最大メモリを制限できます。 UDFを呼び出すクエリ文全体のメモリも制限されます。
PL_CURSOR_MEMORY_LIMITパラメーターを128k (131072) 以上の値に設定し、PL_CURSOR_MEMORY_LIMITパラメーターをPL_MEMORY_LIMITパラメーター以下に設定することを推奨します。
PL_CURSOR_MEMORY_LIMITパラメーターは、各カーソルが占有するメモリを制限するために使用されます。 メモリ制限を超えると、データはハードディスクに保存されます。 PL_MEMORY_LIMITパラメーターは、UDFのメモリを制限するために使用されます。
コール深度の制限
MAX_PL_DEPTHパラメーターを使用して、呼び出しの深さを制限できます。 非常に深い呼び出しは、UDFの実行ロジックを理解することを困難にし、膨大なリソースを消費します。