Performance der Skripte optimieren

do as transaction ... end | do as server ... end | do as deferred ... end

Ninox führt Skripte im permanenten Austausch zwischen Browser bzw. App und dem Server aus. Im Regelfall ist das in Ordnung, da der Austausch schnell genug ist, um ein Skript zügig abzuarbeiten.

In manchen Fällen können Sie die Performance Ihrer Skripte jedoch dahingehend weiter optimieren, indem Sie Anweisungen in spezielle Code-Blöcke setzen.

Mehr zu Tipps und Tricks für schnelle Datenbanken.

do as transaction ... end

Um sicher zu sein, dass Skripte innerhalb derselben Transaktion ausgeführt werden, verwenden Sie am besten do as transaction .

do as transaction wurde insbesondere für die mobilen Apps (iPhone, iPad, Android) und Desktop-App (Mac) entwickelt, um sicherzustellen, dass Skripte auch lokal verarbeitet werden können. Das ist zum Beispiel der Fall, wenn die Internet-Verbindung unterbrochen ist.

Wenn Sie do as transaction in der Web-App verwenden, wird das Skript immer auf dem Server ausgeführt.

Die Verschachtelung von Schleifen- und select-Befehlen ist in der Regel sehr performance-lastig, daher empfehlen wir solche Skripte in einen do as transaction-Block einzusetzen, um den Vorgang zu beschleunigen.

Sollte es warum auch immer zu Problemen bei der Ausführung des Skriptes kommen, wird die Transaktion verworfen, d.h. eine Transaktion wird entweder komplett ausgeführt oder gar nicht.

Mehr zu Transaktionen.

Beispiel

Wir weisen dem Feld Ansprechpartner in jedem Datensatz der Tabelle Firmen einen Ansprechpartner aus der Tabelle Ansprechpartner mit passender ID zu. Der ganze Vorgang wird innerhalb von do as transaction ausgeführt.

do as transaction
	for firma in select Firmen do
		firma.(Ansprechpartner := first(select Ansprechpartner where Id = firma.Id))
	end
end

Ergebnis: Alle Datensätze in der Tabelle Firmen wurden innerhalb einer Transaktion mit einem Eintrag aus der Tabelle Ansprechpartner verlinkt.

do as server ... end

Manchmal kann es vorteilhaft sein, einen Teil Ihres Skripts erst vollständig auf dem Server auszuführen, bevor es zurück an Ihren Rechner bzw. Ihre App geschickt wird.

do as server sollte nicht in Triggern benutzt werden, da Trigger im Browser immer serverseitig und in der App immer lokal ausgeführt werden. Verwenden Sie daher do as server am besten in Buttons.

do as server wird meistens in Verbindung mit der Funktion http() verbunden, um API-Calls zuerst serverseitig auszuführen. Damit wird die CORS-Richtlinie (Cross-origin resource sharing) der Browser umgangen, die ansonsten den http-Aufruf blockieren würde. Anschließend erhalten Sie die angeforderten Daten vom Server.

Mehr zu API-Calls (im Moment nur auf Englisch).

Manche Funktionen können nicht serverseitig ausgeführt werden, da Sie mit Ihrem Browser bzw. mit Ihrer App zusammenhängen, z. B. alert().

Beispiel

Sie möchten in einer Datenbank Daten aus einer Ninox-Tabelle erhalten. Dazu schicken Sie über einen API-Call einen GET-Request an die entsprechende Ninox-Datenbank. Mit dem Punkt-Operator . greifen Sie auf Werte der Response zu.

let response := do as server
		http("GET", "https://api.ninoxdb.de/v1/teams/" + teamId() + "/databases/" + databaseId() + "/tables/" + tableId(this) + "/records", {
			Authorization: "Bearer 0xxx0000-000x-00xx-x0x0-0x0x0000000x"
		}, null)
	end;
response.result

Ergebnis: Hier wird der result-Wert der response zurückgegeben, der in diesem Fall aus nur 1 Datensatz und der in den einzelnen Feldern enthaltenen Informationen besteht.

[{
    "id":1,
    "sequence":129,
    "createdAt":"2021-03-11T08:43:53",
    "createdBy":"xx0xxXX0XxxxXXxXx",
    "modifiedAt":"2022-01-21T14:20:36",
    "modifiedBy":"xx0xxXX0XxxxXXxXx",
    "fields": {
                "Produktname":"Ninox Cola",
                "Produkt-ID":"PID-123456789",
                "Preis":0.99
              }
}]

do as deferred ... end

Normalerweise führt Ninox schreibende Transaktionen der Reihe nach aus.

Tipp: Machen Sie sich mit dem Unterschied zwischen lesenden und schreibenden Transaktionen vertraut.

Es kann dabei vorkommen, dass manche dieser schreibenden Transaktionen mehr Zeit beanspruchen und nachfolgende Transaktionen daher etwas warten müssen. Dies kann dazu führen, dass sich Ninox unerwünschter Weise verlangsamt.

Sie können mit der Anweisung do as deferred dafür sorgen, dass lesende Anweisungen innerhalb einer schreibenden Transaktion in eine eigene (lesende) Transaktion ausgegliedert werden. Dies kann damit im Hintergrund ausgeführt werden.

Sie blockiert somit nicht die nachfolgenden Transaktionen und bietet einen Performance-Boost. 🚀

Aus der Praxis

Wenn Sie zum Beispiel die Daten einer großen Tabelle ändern, kann dies statt einiger Millisekunden mehrere Sekunden dauern. Nachgelagerte Anweisungen müssten dann jeweils so lange warten, bis alle Daten vollständig geändert wurden.

Mit do as deferred kann die Abarbeitung von Anweisungen beschleunigt werden, da Anweisungen, die zwischen do as deferred und end stehen, gesondert abgearbeitet werden und somit andere Prozesse nicht behindern.

Beispiel

Eine Status-Änderung mit einer dadurch ausgelösten E-Mail kann wie folgt optimiert werden:

Sie setzen ein Feld Status = 3. Dadurch löst der im Status-Feld hinterlegte Trigger nach Änderung (s. Code-Block) folgende Anweisungen aus:

  1. das Feld versendet am wird auf das heutige Datum gesetzt

  2. eine E-Mail wird mit einer Zahlungsaufforderung versendet. Dieser Teil wird separat ausgeführt.

if Status = 3 then
	'versendet am' := today();
	do as deferred
		sendEmail({
			from: "absender@domain.com",
			to: "empfaenger@domain.com",
			cc: "empfaenger2@domain.com",
			bcc: "empfaenger3@domain.com",
			subject: "Ihre Rechnung",
			text: "Bezahlen Sie 100 €!"
		})
	end
end

Ergebnis: Alle Datensätze, deren Status auf 3 gesetzt wurde, haben das heutige Datum im Feld versendet am hinterlegt. In einer herausgelösten Transaktion wurde außerdem eine E-Mail mit einer Zahlungsaufforderung an alle Datensätze mit dem Status 3 versendet.

Last updated