Profiling von Handlern für gespeicherte Snowpark (Python)-Prozeduren¶
Mit dem integrierten Code-Profiler können Sie herausfinden, wie viel Zeit oder Speicher für die Ausführung Ihres Handler-Codes aufgewendet wurde. Der Profiler generiert Informationen, die beschreiben, wie viel Zeit oder Speicher für die Ausführung jeder Zeile des Prozedur-Handlers aufgewendet wurde.
Mit dem Profiler können Sie Berichte erstellen, die sich jeweils auf einen der folgenden Punkte konzentrieren:
Zeitaufwand pro Zeile – hier zeigt der Bericht die Anzahl der Ausführungen einer Zeile, die Ausführungsdauer usw. an.
Speicherverbrauch pro Zeile – hier zeigt der Bericht den verbrauchten Speicher pro Zeile an.
Der Profiler speichert den erstellten Bericht in dem von Ihnen angegebenen internen Stagingbereich von Snowflake. Sie können die Profiler-Ausgabe mit der Funktion StoredProcedureProfiler.get_output
lesen.
Bemerkung
Profiling führt zu einem Leistungsaufwand bei der Python-Ausführung und kann die Leistung der Abfrage beeinträchtigen. Sie ist für Entwicklung und Tests gedacht und sollte nicht für kontinuierliche Produktions-Workloads aktiviert werden.
Erforderliche Berechtigungen¶
Wenn eine gespeicherte Prozedur nach dem Aufruf der Funktion StoredProcedureProfiler.set_active_profiler
ausgeführt wird, überprüft Snowflake die folgenden Berechtigungen für den Benutzer, der die Prozedur ausführt:
Sie müssen Lese- und Schreibberechtigungen für den Stagingbereich haben.
Wenn es sich bei der profilierten gespeicherten Prozedur um eine gespeicherte Prozedur mit den Aufruferrechten handelt, müssen Sie eine Rolle mit der Berechtigung USAGE für die gespeicherte Prozedur verwenden.
Wenn es sich bei der profilierten gespeicherten Prozedur um eine gespeicherte Prozedur mit Eigentümerreichten handelt, müssen Sie eine Rolle mit der Berechtigung OWNERSHIP für die gespeicherte Prozedur verwenden.
Einschränkungen¶
Es werden nur gespeicherte Prozeduren unterstützt. UDFs-Unterstützung ist noch nicht verfügbar.
Rekursive Profilerstellung wird nicht unterstützt. Nur Funktionen der obersten Ebene der angegebenen Module werden profiliert, während Funktionen, die innerhalb von Funktionen definiert sind, nicht profiliert werden.
Das Profiling von gespeicherten Prozeduren, die auf der Client-Seite über die
snowflake.snowpark
API erstellt wurden, wird nicht unterstützt.Python-Funktionen, die parallel über
joblib
laufen, werden nicht profiliert.Systemdefinierte gespeicherte Prozeduren können nicht profiliert werden. Sie produzieren keine Ausgabe.
Die Profiling-API muss in demselben Thread verwendet werden, von dem aus die Prozedur aufgerufen wurde.
Verwendung¶
Sobald Sie den Profiler für die Verwendung eingerichtet haben, können Sie ihn verwenden, indem Sie einfach die gespeicherte Prozedur aufrufen, um die Profiler-Ausgabe zu generieren. Nachdem die Prozedur beendet ist, wird die Profiler-Ausgabe in eine Datei im Stagingbereich geschrieben, den Sie angeben. Sie können die Profiler-Ausgabe mit einer Systemfunktion abrufen, wie unten beschrieben.
Folgen Sie diesen Schritten in Ihrem Code, um den Profiler einzurichten und zu verwenden:
Erwerben Sie ein Profiler-Objekt aus dem
Session
-Objekt.Geben Sie den Snowflake Stagingbereich an, in den die Profilausgabe geschrieben werden soll.
Aktivieren Sie den Profiler und legen Sie fest, worauf sich der Profilbericht konzentrieren soll.
Rufen Sie die gespeicherte Prozedur auf.
Profiling-Ausgabe ansehen.
Profiler-Objekt erfassen¶
Erstellen Sie in Python eine Variable vom Typ StoredProcedureProfiler
, mit der Sie den Profiler konfigurieren und ausführen können.
# Create your sesssion
session = Session.builder.configs(CONNECTION_PARAMETERS).create()
# Acquire profiler object
profiler = session.stored_procedure_profiler()
Geben Sie den Snowflake-Stagingbereich an, in den die Profilausgabe geschrieben werden soll¶
Bevor Sie den Profiler starten, müssen Sie einen Stagingbereich angeben, in dem die Ausgabe gespeichert werden soll. Um den Stagingbereich anzugeben, rufen Sie StoredProcedureProfiler.set_target_stage
auf und geben dabei den vollqualifizierten Namen eines internen Snowflake-Stagingbereichs an, in den der Bericht geschrieben werden soll.
Beachten Sie Folgendes:
Der Name des Stagingbereichs muss ein vollqualifizierter Name sein.
Wenn der Stagingbereich, den Sie in diese Funktion eingeben, nicht existiert, erstellt Snowflake einen temporären Stagingbereich mit diesem Namen.
Wenn Sie die Profiler-Ausgabe außerhalb der Sitzung aufbewahren möchten, erstellen Sie einen permanenten Stagingbereich, bevor Sie
set_target_stage
ausführen, und geben Sie den Namen dieses permanenten Stagingbereichs in dem Funktionsaufruf an.Wenn Sie keinen Stagingbereich mit
set_target_stage
festlegen, setzt Snowflake den temporären Stagingbereich der aktuellen Sitzung als Zielbereich ein. Um diesen temporären Stagingbereich zu entdecken, rufen SieSession.get_session_stage
auf.
Der Code im folgenden Beispiel erstellt einen temporären Stagingbereich profiler_output
, der die Profiler-Ausgabe empfängt.
profiler.set_target_stage("mydb.myschema.profiler_output")
Aktivieren Sie den Profiler, indem Sie seinen Fokus festlegen¶
Verwenden Sie die Funktion StoredProcedureProfiler.set_active_profiler
und geben Sie einen Wert an, der angibt, welche Art von Profilbericht Sie erstellen möchten.
Wenn Sie möchten, dass der Profiler über die Aktivität der Zeilennutzung berichtet, setzen Sie den Parameter auf den Wert
LINE
(unterscheidet nicht zwischen Groß-/Kleinschreibung), wie unten gezeigt:profiler.set_active_profiler("LINE")
Wenn Sie möchten, dass der Profiler über die Speichernutzung berichtet, setzen Sie den Parameter auf den Wert
MEMORY
(unterscheidet nicht zwischen Groß-/Kleinschreibung), wie unten gezeigt:profiler.set_active_profiler("MEMORY")
Um den Profiler zu deaktivieren, verwenden Sie die Funktion StoredProcedureProfiler.disable
.
Rufen Sie die gespeicherte Prozedur auf:¶
Nachdem der Profiler aktiviert wurde, ruft Ihre gespeicherte Prozedur auf.
session.call("my_stored_procedure")
Profiling-Ausgabe ansehen¶
Am Ende der Ausführung können Sie mit der Funktion StoredProcedureProfiler.get_output
auf die Ausgabe zugreifen.
profiler.get_output()
Einschließlich zusätzlicher Module für die Profilerstellung¶
Beim Profiling können Sie Module einbeziehen, die standardmäßig nicht enthalten sind.
Standardmäßig werden die in Ihrem Modul definierten Methoden profiliert. Dazu gehören die folgenden Methoden:
Der Methoden-Handler
Im Modul definierte Methoden
Aus Paketen oder anderen Modulen importierte Methoden
Um zusätzliche Module für das Profiling einzubeziehen, verwenden Sie die Funktion StoredProcedureProfiler.register_modules
und geben dabei die Module an, die Sie einbeziehen möchten.
Der Code im folgenden Beispiel registriert die Module module_A und module_B für das Profiling.
profiler.register_modules(["module_A", "module_B"])
Um die Registrierung von Modulen aufzuheben, verwenden Sie register_modules
ohne Argumente, wie im folgenden Beispiel.
profiler.register_modules()
Beispiel¶
Die folgenden Beispiele zeigen, wie Sie den Profiler verwenden, um einen Bericht über die Zeilennutzung zu erstellen und abzurufen.
Der Code in diesem Beispiel erstellt eine Prozedur profiler_test_proc
.
CREATE OR REPLACE PROCEDURE profiler_test_proc()
RETURNS NUMBER
LANGUAGE PYTHON
RUNTIME_VERSION = 3.8
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'main'
AS
$$
from snowflake.snowpark.functions import col, udf
def main(session):
df = session.sql("select 1")
return df.collect()[0][0]
$$;
Der Code im folgenden Beispiel richtet einen Profiler ein und erstellt dann ein Profil für die Prozedur profiler_test_proc
.
profiler = profiler_session.stored_procedure_profiler
profiler.register_modules(["profiler_test_proc"])
profiler.set_target_stage(
f"{db_parameters['database']}.{db_parameters['schema']}.{tmp_stage_name}"
)
profiler.set_active_profiler("LINE")
profiler_session.call("profiler_test_proc")
res = profiler.get_output()
print(res)
profiler.disable()
profiler.register_modules([])
Die generierte Ausgabe des Zeilen-Profilers sieht wie folgt aus:
Handler Name: main
Python Runtime Version: 3.8
Modules Profiled: ['main_module']
Timer Unit: 0.001 s
Total Time: 0.0619571 s
File: _udf_code.py
Function: main at line 4
Line # Hits Time Per Hit % Time Line Contents
==============================================================
4 def main(session):
5 1 0.4 0.4 0.6 df = session.sql("select 1")
6 1 61.6 61.6 99.4 return df.collect()[0][0]