Performance

24. April 2006 15:15

Hallo,

ich möchte heute einen Sammeltoppic zum Thema Performance starten!
Wenn ausreichend Informationen zusammengekommen sind, könnte ein entsprechendes Thema mit einer Übersicht in Tipp´s & Tricks erstellt werden.

Mein bisheriger Kenntnisstand zum Aufrufen von Records (Bitte Korrigieren, wenn ich falsch liege):
Ein GET auf einen Record ist die Schnellste Zugriffsvariante. Jedoch nur auf den Primärschlüssel möglich!

Die zweitschnellste ist das Filtern mit einen SETRANGE zusammen mit einem FIND.
Der Zugriff verbessert sich wesentlich wenn vorher ein SETCURRENTKEY auf die gefilterten Felder gemacht wird.

Nun zu meiner Frage:
Wenn eine Tabelle mit einem SETFILTER (deutlich langsamer als SETRANGE) gefiltert wird und mit einem FIND der Datensatz gesucht wird,
bringt auch hier ein SETCURRENTKEY schneller die Ergebnisse?

Gruß Mikka
Zuletzt geändert von mikka am 14. Februar 2007 10:57, insgesamt 1-mal geändert.

24. April 2006 15:21

Grundsätzlich gilt:

Je optimaler der verwendete Schlüssel (SETCURRETKEY) um so schneller die Ergebnisse, Mikka.

Grüße
Gerhard

24. April 2006 18:52

Wird Navision unter der SQL-DB betrieben, ist es eminent wichtig, vor jedem SETRANGE/SETFILER den optimalen Schlüssel zu setzen. Also einen Schlüssel, der am optimalsten alle zu filternden Felder enthält. Wenn die Filter in der Reihenfolge gesetzt werden, wie die Felder im Key drin sind, bringt das weitere Vorteile. Auch bei einem Zugriff über GET wird empfohlen, vorher den Schlüssel (also den Primärkey) mit SETCURRENTKEY zu setzen.

25. April 2006 07:51

Gruesse,

zum Thema Performance faellt mir folgendes ein, auch wenn das schon recht bekannt sein muesste. :wink:
Externe Zugriffe auf Navision sind mit C/FRONT um ein vielfaches schneller als mit ODBC z.B.

Gruesse
feri

25. April 2006 09:37

Rotsch hat geschrieben:Auch bei einem Zugriff über GET wird empfohlen, vorher den Schlüssel (also den Primärkey) mit SETCURRENTKEY zu setzen.


Das macht Sinn (Ich bin mir aber nicht sicher, ob Navision nicht sowieso beim GET die richtige Sortierreihenfolge nimmt! ?), wenn vorher ein anderer Schlüssel vorher gewählt wurde. Also solllte ein RESET immer Vorher ausgeführt werden, sofern die Filterung nicht für weitere Schritte benötigt wird.

feri hat geschrieben:Externe Zugriffe auf Navision sind mit C/FRONT um ein vielfaches schneller als mit ODBC z.B.


Stimmt, ebenso sind In-/Exports mit Textdateien noch langsammer als ODBC Zugriffe!

Gruß Mikka

25. April 2006 09:57

mikka hat geschrieben:Ich bin mir aber nicht sicher, ob Navision nicht sowieso beim GET die richtige Sortierreihenfolge nimmt! ?), wenn vorher ein anderer Schlüssel vorher gewählt wurde.


Das Setzen des Primärkeys vor dem Ausführen eines GET wird von MBS empfohlen, jedoch nur für Navision auf SQL. Die Native-DB optimiert das selber.

25. April 2006 16:28

Bei Einsatz von Navision 4.00 in Verbindung mit einem SQL-Server ist ein FINDFIRST deutlich schneller als ein FIND('-').
Das Gleiche gilt für FINDLAST und FIND('+').
Um den optimalen Schlüssel für (vom Anwender gesetzte Filter) zu finden, gibt es hier im Download Center die Codeunit RecRefManagement.
Diese Codeunit enthält u. a. die Funktion GetBestKey(VAR RecRef : RecordRef;HideDialog : Boolean) KeyFound : Boolean, welche anhand der gesetzten Filter den optimalen Schlüssel (inkl. Berücksichtigung der Position innerhalb des Schlüssels) findet.

25. April 2006 20:37

Merkwürdigerweise ist der Inhalt der Mail irgendwie verlorengegangen beim Speichern, daher nochmal:

Wenn man durch einen ganzen Satz von Records gehen muss um Daten zu lesen, ist das allerschnellste auf dem SQL der FINDSET Befehl.

if MyRec.FINDSET(false,false) then repeat
DoSomething:= MyRec.Fieldname oder sowas
until MyRec.NEXT=0;

schneller gehts nirgendwo.
Zuletzt geändert von Michael Schumacher am 26. April 2006 00:47, insgesamt 1-mal geändert.

25. April 2006 20:59

Das sind ja schon einige gute Vorschläge.

Ich habe heute den DBMS Cache höher gesetzt. In den Navision Unterlagen steht eine Formel zu Berechnung des DMBS Caches. (Aus Zeitmangel nachzulesen und wie der Syntax der Befehlszeile unter 2.6 habe ich unseren MBS-Partner gefragt :oops: 8-) )
Wie sind Eure Erfahrungen, kann man sich an die Formel halten, oder sollte ehr etwas weniger oder mehr angegeben werden?

Zweite Frage: Navision bietet den Commit Cache, der die zu Schreibenen Daten zwischenspeichert, bevor diese auf die Festplatte geschrieben wurden, dadurch erhöht sich die Arbeitsgeschwindigkeit wesentlich.
Ich habe zu diesen Cache bisher nirgens eine Empfehlung lesen können (..oder bin ich Blind?) , ausser das der Empfehlung diesen einzuschalten.
Gibt es zu diesen auf den Clients eine Empfehlung (abhängig vom Arbeitsspeicher und der ausgeführten Programme)?

Gruß Mikka

25. April 2006 22:44

Es gibt nicht "die" Formel. Jeder MBSP hat da möglicherweise seine eigenen Erfahrungen gemacht.

Ich arbeite z. B. mit folgender Formel:
Mit dem Task-Manager feststellen, wieviel physikalischer Arbeitsspeicher noch verfügbar ist, wenn alle Dienste (inkl. Navision-Server) auf dem Server laufen.
Der DBMS-Cache sollte so groß wie möglich eingestellt sein, aber niemals größer sein, als der physikalisch verfügbare Arbeitsspeicher.
Unter gewissen Umständen (mehrere Navision-Serverdienste auf einem Server, mehrere Datenbankteile, ...) muss diese Formel allerdings an die Gegebenheiten angepasst werden.
Sobald der Server anfangen müsste zu swappen (auszulagern), geht die Performance drastisch (und kritisch) in den Keller!

Commit cache läuft voll

18. Januar 2007 18:28

hallo...
wie schön dass ich euch hier gesammelt antreffe...

ich habe nämlich sei kurzem ein problem. bei uns läuft navision 3.7 auf einem windows 200 server mit 2gb ram.
es kommt in letzte zeit immer öffter zu performance problemen. das öffnen von einem einfachen fenseter in navision (z.b. gebuchte rechnung) dauert lang und buchungen bzw. berichte lassen lange auf sich warten. hin und wieder erscheint dann die meldung "commit cache ist voll"!!

der dbms-cache ist auf 1.000.000 eingestellt. das ist zumindest im fenster "datenbankinformation" zu lesen. ( über extras->optionen wird aber für dbms cache der wert <8000> angezeigt. warum ist das bloß so?)
über den taskmanager habe ich gesehen dass der server.exe 1.000.000 speicher belegt.

ich habe keine idee was nun zu tun ist und warum der cache immer wieder voll läuft.

hat jemand eine idee was ich da ändern kann.

viele grüße
shahram

18. Januar 2007 19:34

Michael Schumacher hat geschrieben:Wenn man durch einen ganzen Satz von Records gehen muss um Daten zu lesen, ist das allerschnellste auf dem SQL der FINDSET Befehl.

if MyRec.FINDSET(false,false) then repeat
DoSomething:= MyRec.Fieldname oder sowas
until MyRec.NEXT=0;


Wobei hier AUF JEDEN FALL wichtig ist, dass es sich um Datenmengen handelt, die sich innerhalb der konfigurierten Grenzen halten (Datei -> Datenbank -> Ändern... -> Erweitert -> Datensatzmenge). Obiges Konstrukt ist nur schneller, wenn die Menge der Datensätze die konfigurierte Anzahl (Standard 500) nicht überschreitet. Ansonsten sollte man weiterhin old school mit (FIND('-') und FIND('+')) arbeiten. Also sicherlich gut für kleine Tabellen wie Country/Currency usw. aber schlecht für z.B. Posten.

19. Januar 2007 12:58

Hallo zusammen!

Ich begrüße es sehr, daß hier soz. mein Spezialgebiet aufgegriffen wird!
Deshalb fühle ich mich auch veranlasst, ein paar der ... ähm ... nennen wir's "üblichen Mistverständnisse" klarzustellen, wenn es um NAV & SQL Server geht.

(Kurz Vorweg: Das Thema ist freilich etwas komplexer, als es hier dargestellt werden kann. Normalerweise führe ich hierzu eine min. 2-tägige Grundlagenschulung für NAV Partner durch)

Zum Thema Keys & Indexes in NAV:

Während beim nativen Server (FDB) ein Key/Index dazu benutzt wird Datensätze zu finden UND die Sortierung zu bestimmen UND die SIFT Strukturen zu definieren, so sind dies uner SQL Server "getrennte Paar Schuhe": SQL Server verwendet einen Index AUSSCHLIESSLICH zum Auffinden von Datensätzen.
Wenn C/SIDE soz. C/AL in SQL übersetzt, so bestimmt ein SETCURRENTKEY lediglich die Sortierung (also die ORDER BY Clause). Welchen Index der SQL Server hierbei benutzt, eztscheidet der SQL Query Optimizer selbst auf Basis von Statistiken!
Natürlich versucht SQL Server idealerweise einen Index zu verwenden, der der ORDER BY clause entspricht, entscheidet sich aber in vielen Fällen dagegen oder verwendet ihn suboptimal (für die SQL Fraktion: statt 'nem Index Seek erfolgt ein Index Scan oder - noch schlimmer - ein Clustered Index Scan).
Heißt also im Klartext: SETCURRENTKEY hat nur mittelbar etwas mit Performance zu tun. Da i.d.R. die NAV Primärschlüssel in SQL zum PRIMARY KEY CLUSTERED werden, ist es in vielen Fällen sogar hilfreich, auf das SETCURRENTKEY zu verzichten. Oder anders ausgedrückt: SETCURRENTKEY sollte man nur verwenden, wenn die Sortierung wirklich eine Rolle spielt, wie z.B. beim Gruppieren.
Des Weiteren: SETFILTER und SETRANGE (sowie "filternde" Eigenschaften wie TableView, etc.) werden in SQL zur WHERE Clause. Es ist daher unerheblich - nur mit SQL Server - ob man SETRANGE oder SETFILTER verwendet, ebenso die Reihenfolge der angewendeten Filter.

Wenn man über Performance und Indexe spricht, so bleibt festzustellen, daß C/SIDE die SQL Indexe äußerst mangelhaft erstellt, wenn ein NAV Key zum SQL Index wird (auch unter Nutzung der 4.00 Features hier).
Will man die Performance steigern, so müssen die Indexe in besonderer Weise SQL Server seitig überarbeitet werden - keine Chance von NAV Seite. Tut man das - und zwar richtig!!! - kann man die Transaktionsgeschwindigkeit locker im Durchschnitt verfünffachen (mindestens, mein persönlicher Spitzenreiter ist bei 50x - fünfzig fach! -schneller!).

Das nur mal in aller Kürze ... to be continued ...

19. Januar 2007 13:27

Hallo Jörg, verstehe ich das jetzt richtig, dass ein zusätzlicher Index wohl was bringt, wenn in diesem Feld z.B. auf <>0 gefiltert werden soll?
Ich vermute aber mal, dass das erstellen dieses Index fast genau so lange dauern wird, wie das einmalige Filtern auf Datensätze <>0
Diese Spalte brauche ich nämlich nur einmal beim Erzeugen von 190 Millionen Varianten eines Artikels aus der Multiplikation von 6 Attributen und daraus resultierenden Aufpreisen bei bestimmten Attributen, um daraus dann entsprechende Einträge in Sales Price zu erzeugen.
Damit er nicht alle 190 Millionen Varianten einliest, filtere ich halt die aus, wo was drinsteht, dauert dann aber mehrere Minuten, bis er den ersten hat....

19. Januar 2007 13:57

Hi Michael!

Na ja, prinzipiell erleichtert jeder Index das Auffinden der Daten, d.h. die Leseleistung kann erhöht werden. Andererseits erhöht man mit zusätzlichen Indexen natürlich die "Costs per Record" also die Schreib-Leistung wird verschlechtert.

Es ist also unsinnig pauschal zu sagen, für jedes Filterfeld einen Index zu erstellen. Indexe sollten Felder der WHERE Clause beinhalten, die eine hohe Selektivität haben. Wird allerdings versucht, die Selektivität "krampfhaft" zu erhöhen - in dem man z.B. jedem Index die Primärschlüsselfelder hinzufügt (NAV Standard!!!) - geht der Schuss nach hinten los, der Index wird "wertlos" und nicht/schlecht genutzt.

Weiterhin hängt der "Wert" eines Indexes von der statistischen Verteilung der Feld-Werte ab: Indiziert man z.B. ein Feld "Document No." so erzielt man schnelle Abfragen wenn im Prinzip jede Nummer anders ist. Unterscheiden sich die "Document No." kaum - z.B. 50% = 1, 50% = 2 - so wird der Index u.U. nicht genutzt, da SQL Server bei einer Abfrage genötigt ist 50% der Datensätze zu lesen.

Ausserdem "arbeiten" Indexe oft zusamen - z.B. die Non-Clustered-Indexes mit den Clustered Indexes; d.h. hier spielt auch die physikalische Anordnung der Datensätze eine Rolle.

Der richtige Index hängt also prinzipiell immer von der Art der Abfrage und der Struktur der Datensatzverteilung ab.
Pauschale Regeln lassen sich hier nur schwer formulieren ...

19. Januar 2007 20:56

Jörg, zu einem deiner obigen Punkte eine Frage. Ich weiss selbst, dass Optimierungen immer von der jeweiligen Datenbank, dem überwiegenden Nutzungsverhalten und vielen weiteren Faktoren abhängen.

Ein kurzes Praxisbeispiel wäre hier für mich sehr hilfreich. So ala Kunde X hat Y Daten in Tabelle Z. Aufgrund von A und B waren Vorgänge im Bereich C der oft genutzt wurde sehr langsam. Deshalb wurde ...

Du sagst, dass diverse Optimierungen im Schüsselbereich nur direkt auf dem SQL Server möglich sind. Kannst du dazu auch ein Beispiel geben? Ich müsste ja bei Schlüsseländerungen innerhalb von Navision (an diesen speziellen Keys), die Änderungen auf SQL Ebene wiederholen um den geänderten schnellen Zustand wieder herzustellen!?

Gerne das ganze auch kurz und bündig. Weiterführende Infos kann ich mir dann auch aus dem Internet holen.

20. Januar 2007 12:00

Hi Carsten!

Nun, im Anhang einen kurzen Auszug aus meinem "NAV & SQL Performance Field Guide" (ein Dokument, das ich ausschließlich an meine "Schüler"/Clienten verteile), welcher einige Grundsätze zum Thema "Indexes" erläutert und auch ein kleines Erklärungs-Beispiel im Kontext "Sales Line" beinhaltet.

Zur Durchführung von Index-Änderungen:
Grundsätzlich gilt: Überflüssige Indexe deaktivieren ("MaintainSQLIndex" = FALSE)
NAV mit Versionen kleiner 4.00 bietet keine NAV seitigen Möglichkeiten, einen SQL seitigen Index anders aufzubauen als den NAV Key, hier muss man die Änderungen SQL Server seitig vornehmen.
Seit 4.00 ist diese Änderung möglich: Eigenschaften "SQL Index" und "Clustered"
Änderungen wie das Entfernen überflüssiger PK Felder und des UNIQUE Flags, das Setzten von optimalen Füllfaktoren oder das physikalische verschieben von Indexen ist nur SQL Server seitig möglich.

"SQL Server seitig" heißt konkret, die entsprechende Anwendung von TSQL: ALTER TABLE, CREATE INDEX, sp_helpindex, dbcc show_statistics, u.v.m..
Wer hier "rumfummelt" sollte wirklich GANZ GENAU wissen was er tut, da Fehler hier nicht verziehen werden und man schlimmsten Falls das gesamte System soz. "durch 's Klo spült" ...

Wie schon in meinem ersten Posting in diesem Thread erwähnt: Die ganze Thematik ist etwas zu komplex um sie hier vollständig darzustellen ...
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

20. Januar 2007 13:09

Danke Jörg,

der Punkt mit dem Anhängen des PK und UNIQUE war mir bisher in sofern nicht klar, als dass ich annahm NAV würde diese Konstellation intern benötigen. Wenn auch die abgesetzten SQL Statements das nicht unbedingt vermuten ließen.

Wir haben auf unserer Agenda schon länger den Punkt SQL Optimierung, aber immer wieder verschoben. Aktuell aufgrund unseres Db Updates von 3.70 auf 4.0 SP3, um erstmal diesen schon etwas optmierteren Stand zu haben. 4.0 wird dann die Basis für unsere Ansätze sein.

Ich könnte mir vorstellen, dass wir uns dann auch gern mal persönlich für 1-2 Tage bei uns treffen. ;-)

20. Januar 2007 13:34

Danke Jörg,
jetzt hab ich auch endlich verstanden, was der Unterschied zwischen CI und NCI ist!

20. Januar 2007 16:34

Ich könnte mir vorstellen, dass wir uns dann auch gern mal persönlich für 1-2 Tage bei uns treffen.

Gerne, hab' noch Termine frei 8-)

jetzt hab ich auch endlich verstanden, was der Unterschied zwischen CI und NCI ist!

Ich freue mich immer wenn ich helfen kann! :-)

Schönes Wochenende!

5. Februar 2007 10:24

Hab ich das jetzt richtig verstanden?
Unser Kunde betreibt eine SQL-Datenbank, unsere Entwicklungsdatenbank ist es aber nicht.
Soll ich statt jedem SETCURRENTKEY das hier schreiben?:
Code:
IF NOT RECORDLEVELLLOCKING THEN
  SETCURRENTKEY(...);

5. Februar 2007 10:43

Hi Natalie!

Nun, pauschal kann man das nicht sagen, es kommt wirklich auf jede einzelne Abfrage an, aber in einigen Fällen kann man damit wirklich schnellere Abfragen erreichen:

Ohne SETCURRENTKEY wird der Primärschlüssel = Clustered Index (in NAV!) genutzt, also als ORDER BY. Dieser Index wird früher oder später sowieso genutzt, da die Leaf Nodes des CI die Daten enthalten.
Ohne SETCURRENTKEY bekommt nun der SQL Server die Chance, den optimalen Index für die WHERE Clause zu finden; störendes Umsortieren entfällt.

Oft merkt man aber auch keinen Unterschied, weil der gewählte Index quasi dem SETCURRENTKEY entspricht.

Soz. als "Anhalt" kann man sagen, daß wenn auf Felder gefiltert wird, die nicht Teil eines Index sind, dann sollte man lieber kein SETCURRENTKEY verwenden, als ein "schlechtes".

Am besten einfach ausprobieren (mit SQL Profiler messen) ...

25. Juni 2007 12:06

Ich möchte nach Setzen von Filtern nur herausfinden, ob (irgend)ein Datensatz existiert.

Was ist schneller?
ISEMPTY oder NOT FINDFIRST?

25. Juni 2007 12:28

isempty

3. August 2007 15:55

Hallo Jörg,

ich habe Deine Schulungsunterlagen heruntergeladen und habe dann mal etwas mit den Indizies in unseren Sachposten gespielt (natürlich auf Test).
Wir haben auf dem Sachkonto ein eigenes Feld => Offen (so wie in den Debposten auch).

Navision Key habe ich angelegt als
Sachkonto
Offen

SQL mäßig entsteht so der Index
Sachkonto
Offen
Lfd. Nr.
= Eindeutig.
Jetzt habe ich einen 2ten Index angelegt, auf dem SQL Server
Sachkonto
Offen
nicht eindeutig.

Dann habe ich meine Abfrage im Navision gemacht und mit dem Profiler abgefangen.

Punkt 1) er macht ja mehrere Abfragen daraus, aber ich glaube die erste ist die Ausschlaggebende => die habe ich mir gegriffen und dann mal direkt laufen lassen.

Raus kam folgende SQL Abfrage
SELECT * FROM "JWFIN_Heike"."dbo"."Jack Wolfskin$Sachposten"
WHERE (("Sachkontonr."='17722'))
AND (("Offen"=1))
ORDER BY "Sachkontonr."
OPTION (FAST 5)

Es handelt sich hier um ein riesen Konto - zugegeben - trotzdem erstaunt mich das Resultat, denn der Server bediente sich dem Clusterd index i.e. Lfd.Nr. Geschätzte CPU Kosten 14,439

Also noch mal gleichen Select mit WITH (INDEX = $Mein Index)

Geschätzte CPU Kosten 3,2588 auf meinem Index + 0,001591 auf dem Clustered Index.

Aber von selbst - obwohl ich auch update statistics gemacht habe und er ja durch den 2ten SQL Befehl auch eigentlich merken müssen das dieser Index besser ist - er benutzt ihn nicht!!!!
Es ist zum Verzweifeln. Ich bin auch nicht so firm in SQL gebe ich ja zu. :oops: Mit Nativ ging das alles soooo schön einfach!

Wenn ich die gleiche Abfrage noch mal starte mit einem Konto für das kaum Einträge besteht, dann macht er es genau richtig!!!????

Wir haben riesen Laufzeitprobleme und ich hatte halt gehofft das ich durch Deinen Handout vielleicht was hinkriege aber irgendwie bin ich nicht sehr optimistisch wenn ich mir diese Resultate anschaue!

Danke Gruß
Sandra