[Gelöst] SQL viele Reads - Langsam

15. November 2011 02:07

Hallo

Langsam begreife ich gar nichts mehr!! :-(

Die Abfrage;
Code:
SELECT TOP 1 "timestamp","No_", weitere Felder...,DATALENGTH("Picture") FROM "Dynamics NAV"."dbo"."Mandant AG$Item" WITH (READUNCOMMITTED)   WHERE (("Old Catalog No_"=@P1)) AND (("No_"<>@P2)) ORDER BY "Old Catalog No_","No_" OPTION (OPTIMIZE FOR UNKNOWN)

verursacht jedesmal mehr als 67'000 Reads!!

Es gibt einen Index, der die beiden Felder Catalog No_ und No_ beinhaltet.

Eckdaten:
- NAV 2009 R2, Classis Client
- SQL-Server 2008 R2 64 bit, mit 20 GB RAM, virtualisiert mit Citrix XEN-Server
- 270'000 Artikel
- Das Feld Picture ist leer. Keine Bilder zu Artikel vorhanden
- Build 32441 und 32843 (beide probiert)

Hat mit jemand einen Tipp, wo ich ansetzen könnte?

Vielen Dank
Zuletzt geändert von martinst am 15. November 2011 13:05, insgesamt 1-mal geändert.

Re: SQL viele Reads - Langsam

15. November 2011 09:39

Schau mal was passiert wenn du DATALENGTH("Picture") weglässt.

Re: SQL viele Reads - Langsam

15. November 2011 09:52

Schau mal was passiert wenn du DATALENGTH("Picture") weglässt.


Nichts, bzw. kann ich ja nicht. :-(
Das Feld Picture ist ja ein Feld in NAV und die SQL-Statements werden ja durch NAV gebildet.


Gruss

Re: SQL viele Reads - Langsam

15. November 2011 10:26

Hallo,

ich weiss nicht ob es was bedeutet, aber der Schlüssel den du als vorhanden angibst, ist "Catalog No_", in der Abfrage wird "Old Catalog No_" verwendet.


Das ist hier aber wahrscheinlich nicht das Problem, sondern der "Select TOP 1" in der Abfrage. Wie sieht denn der CAL- Code aus, der die Abfrage erzeugt?

Gruß, Fiddi

Re: SQL viele Reads - Langsam

15. November 2011 11:16

Hallo Fiddi

ich weiss nicht ob es was bedeutet, aber der Schlüssel den du als vorhanden angibst, ist "Catalog No_", in der Abfrage wird "Old Catalog No_" verwendet.

Das sehe ich nicht. Wo meinst Du?

NAV-Code:
Code:
Item.RESET;
Item.SETCURRENTKEY("Old Catalog No.");
Item.SETRANGE("Old Catalog No.", GroesseNr);
IF Item.FINDFIRST THEN BEGIN
  EXIT(TRUE);
END;


Komisch, das Ganze.

gruss

Re: SQL viele Reads - Langsam

15. November 2011 11:27

ich weiss nicht ob es was bedeutet, aber der Schlüssel den du als vorhanden angibst, ist "Catalog No_", in der Abfrage wird "Old Catalog No_" verwendet.


Das sehe ich nicht. Wo meinst Du?


Du schreibst:
Es gibt einen Index, der die beiden Felder Catalog No_ und No_ beinhaltet.


Deine SQL- Abfrage läuft aber mit:
SELECT TOP 1 "timestamp","No_", weitere Felder...,DATALENGTH("Picture") FROM "Dynamics NAV"."dbo"."Mandant AG$Item" WITH (READUNCOMMITTED) WHERE (("Old Catalog No_"=@P1)) AND (("No_"<>@P2)) ORDER BY "Old Catalog No_","No_" OPTION (OPTIMIZE FOR UNKNOWN)

Aber zurück zum Thema:

Der SQL- Befehl tut genau das was du programmiert hast: Hole mir den ersten Datensatz (TOP 1, bzw. Findfirst), der zu meinen Selektionskriterium passt. Da kannst du dem System keinen Vorwurf machen. :wink: Wenn du das schneller haben willst, musst du den Artikelstamm mit FINDSET. REPEAT..UNTIL next=0 durchlaufen. Aber das ist abhängig von dem restlichen Code, der drumherum läuft.


Gruß, Fiddi

Re: SQL viele Reads - Langsam

15. November 2011 11:34

Du schreibst:

Es gibt einen Index, der die beiden Felder Catalog No_ und No_ beinhaltet.


Blöd, mein Fehler. da habe ich vertippt.

Sorry.

Zurück zum Thema.
Ich dachte, SetCurrentKey und Findfirst sei schon das schnellste mit Ausnahme von IsEmpty. Nicht???????

Gruss

Re: SQL viele Reads - Langsam

15. November 2011 11:44

Ich dachte, SetCurrentKey und Findfirst sei schon das schnellste mit Ausnahme von IsEmpty. Nicht???????


Trotzdem muss er mindestens einen READ machen, um den Datensatz zu laden :wink: . Evtl. bringt hier ein "NOT Item.ISEMPTY" etwas, weil dann dann das "Order By", "TOP 1", bzw. auch die zurückgegeben Felder entfallen könnten (wenn NAV es denn so übersetzt :wink: ).

Gruß, Fiddi

Re: SQL viele Reads - Langsam

15. November 2011 11:47

Also dein oben geposteter Code ist schon grundsätzlich OK. Allerdings passt der ja nicht zum SQL-Statement. Insofern ist das schon mal schwierig zusammenzubringen.

Was du aber beachten solltest. Nur weil du in NAV ein SETCURRENTKEY machst, heißt das nicht, dass der SQL-Server den von dir erwarteten Index verwendet. Du hast ja auch einen Filter auf das Feld "Nr." gesetzt und da der SQL-Server selber entscheidet, welcher Index verwendet wird, könnte es auch sein, dass der Primärschlüssel verwendet wird und danch dann entsprechend deines SETCURRENTKEY sortiert wird.

Aufgabe: Richtigen Quellcode und korrektes SQL-Statement posten. Denn es gibt so viele Faktoren, die wir nicht prüfen können. Gehört das Statement zu dem von dir beschriebenen Code oder vermutest du das nur? Existiert der Index wirklich auf dem SQL-Server? Welcher Index wird für die Abfrage verwendet? ...

Re: SQL viele Reads - Langsam

15. November 2011 11:49

Trotzdem muss er mindestens einen READ machen, um den Datensatz zu laden

OK, ich schreibe meinen Code um, damit er gar keine Abfrage mehr machen muss :-)
Ich kann ja alle 270'000 Artikel im C/AL Code fest verdrahten. :lol:
Wir wollen das Ding ja nicht überfordern, ist ja nur ein SQL-Server :evil:

IsEmpty kann ich nicht verwenden, da die Variable Item Global ist, und die Feldinhalte eben schon benötigt werden.

Re: SQL viele Reads - Langsam

15. November 2011 11:58

Tim

Was du aber beachten solltest. Nur weil du in NAV ein SETCURRENTKEY machst, heißt das nicht, dass der SQL-Server den von dir erwarteten Index verwendet.

Kenn ich, aber was soll ich sonst machen, ausser ein SetCurrentKy?

Du hast ja auch einen Filter auf das Feld "Nr." gesetzt und da der SQL-Server selber entscheidet,

Nein mache ich nicht. Das mach NAV selber. Der SQL-Index auf die Katalog Nr. wird von NAV ja automatisch mit der Nr. (PK) kombiniert und als Unique angelegt.
Eine Filter auf "No." <> '' gibt es im NAV-Code nirgends.

welcher Index verwendet wird, könnte es auch sein, dass der Primärschlüssel verwendet wird und danch dann entsprechend deines SETCURRENTKEY sortiert wird.

Das ist genau so. Er verwendet "Mandant AG$Item$0", also den PrimaryKey.

Gruss

Re: SQL viele Reads - Langsam

15. November 2011 12:06

Hast Du es mit NOT ISEMPTY ausprobiert, wie fiddi schrieb? Besteht das Problem noch?

Re: SQL viele Reads - Langsam

15. November 2011 12:08

welcher Index verwendet wird, könnte es auch sein, dass der Primärschlüssel verwendet wird und danch dann entsprechend deines SETCURRENTKEY sortiert wird.



Das ist genau so. Er verwendet "Mandant AG$Item$0", also den PrimaryKey.


Der SQL-Server verwendet den Primärschlüssel immer dann für einen SEEK , wenn ihm der angebotene Schlüssel nicht selektiv genug erscheint. Das bedeutet, er müsste nach dem Schlüssel eh jeden zweiten Datensatz lesen, dann benutzt er den Primärschlüssel, um alle Datensätze zu lesen. Das ist nicht unbedingt falsch.

P.S.: auch in der Native-DB ist der Primärschlüssel Bestandteil jedes Sekundärschlüssels

Gruß, Fiddi

Re: SQL viele Reads - Langsam

15. November 2011 12:38

Ich fürchet Fiddi hat Recht.

Die Selektivität könnte es sein.
Bei diesem Kunden habe zu 100'000 Artikel keine Katalognummer. 170'000 haben eine.
Also habe ich mal den NAV-Code mit der Suche nach Katalog-Nummer auskommentiert.
Nun wird nur noch nach Nr. (PK) und EAN-Code gesucht.
Das Ergebniss ist nicht besser. Immer noch 67'342 Reads.
Allerdings wird vermutlich beim EAN auch die Selektivität das Problem sein. Viel EAN-Codes sind bis auf die letzte 2-3 Stellen identisch. :-(

So ziemlich aufgeschmissen...

Re: SQL viele Reads - Langsam

15. November 2011 12:43

Wurde schon NOT ISEMPTY ausprobiert?

Re: SQL viele Reads - Langsam

15. November 2011 12:52

Ich habs gefunden.

Schande über mich

Dieser Code ist der Übeltäter. Den habe ich wirklich nicht gefunden.
Code:
Item2.RESET;
Item2.SETCURRENTKEY("Catalog No.");
Item2.SETRANGE("Catalog No.", GroesseNr);
Item2.SETFILTER("No.", '<>%1', "Item No. NAV");
 IF Item2.FINDFIRST THEN BEGIN


Sorry und besten Dank für die Tipps.
Nun muss ich scahuen, wie ich das besser hinkriege.

Gruss

Re: SQL viele Reads - Langsam

15. November 2011 12:58

Puh, und ich hatte mich beim Mitlesen die ganze Zeit gewundert, wie der zuerst von dir genannte Code das AND (("No_"<>@P2)) hätte verursachen sollen ...

[Gelöst] SQL viele Reads - Langsam

15. November 2011 13:04

Puh, und ich hatte mich beim Mitlesen die ganze Zeit gewundert, wie der zuerst von dir genannte Code das AND (("No_"<>@P2)) hätte verursachen sollen ...


Ich auch. Ich habe die Welt nicht mehr verstanden.
Aber Schukd bin ja ich, und nicht NAV :-D

Danke für alle Tipps.

Re: SQL viele Reads - Langsam

15. November 2011 14:34

martinst hat geschrieben:Dieser Code ist der Übeltäter.
Code:
Item2.RESET;
Item2.SETCURRENTKEY("Catalog No.");
Item2.SETRANGE("Catalog No.", GroesseNr);
Item2.SETFILTER("No.", '<>%1', "Item No. NAV");
 IF Item2.FINDFIRST THEN BEGIN

[Klugscheiß-Modus]
*räusper*
Tim hat geschrieben:Also dein oben geposteter Code ist schon grundsätzlich OK. Allerdings passt der ja nicht zum SQL-Statement.
[/Klugscheiß-Modus]

Re: [Gelöst] SQL viele Reads - Langsam

15. November 2011 14:35

Ich weiss :oops: :oops: :oops:

Obschon ich überzeugt war, dass NAV den Filter auf das Feld No. selber ergänzt.
Irgendwie war ich so festgefahren.

Sorry

Re: [Gelöst] SQL viele Reads - Langsam

15. November 2011 14:38

Nein, ein "Sorry" ist nicht notwendig. War nur Spaß! :-)

Re: [Gelöst] SQL viele Reads - Langsam

15. November 2011 14:42

Ich sollte eben nicht um 02:00 Uhr solche Beiträge posten :-D

Das nächste mal wenn ich ein solches Problem habe, gehe ich ins Bett und schaue mir die Sache am nächsten Tag nochmals an.
Das wäre wohl auch in diesem Fall hier besser gewesen.

Gruss

Re: [Gelöst] SQL viele Reads - Langsam

16. November 2011 08:49

Allerdings wird vermutlich beim EAN auch die Selektivität das Problem sein. Viel EAN-Codes sind bis auf die letzte 2-3 Stellen identisch.


Das macht nichts, es zählt immer das ganze Feld. Der Schlüssel muss aber auch mit der EAN beginnen, damit er Ihn nimmt.

Gruß, Fiddi

Re: [Gelöst] SQL viele Reads - Langsam

22. November 2011 18:52

NAV-Code angepasst -> Viel besser :-D

Gruss und Danke für alle Hinweise