SQL Abruf Performance Problem

  • VB.NET
  • .NET 4.5

Es gibt 38 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    Das ist bei mir nun ja der Teststand, mehr wollte ich damit auch nicht sagen.



    sql enthält auch diese Spalten:
    Spoiler anzeigen

    Quellcode

    1. Select dtbase.id1 as 'Art', dtbase.id2 as 'Gattung', dtbase.id3 as 'Familie', dtbase.id4 as 'Ordnung', dtbase.id5 as 'Klasse', dtbase.id6 as 'Stamm', bonustable.col1 as 'avgGewicht', bonustable.col2 as 'Hauptnahrungstyp' From dtbase Left Join bonustable On dtbase.id1 = bonustable.id1 and dtbase.id2 = bonustable.id2 Order By dtbase.id3, dtbase.id2, dtbase.id1


    Aber der Spaltenname gefällt ihm nicht



    ArtColumn hingegen ist ein Member

    columnArt gibts auch und da gibts noch n komischen Fehler, vielleicht hilft der weiter?

    Wie kann man an einer Spalten denn den Modifizierer ändern?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Ja, jetzt hab ich das nochmal ganz banal reproduziert, ohne Datenanbindung. Nur DataSet, Datagridview, Verbinden und den LINQ Befehl:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    3. Dim view = From t In DS1.dtbase Where DS1.dtbase.Art = 1 Select t
    4. End Sub
    5. End Class


    Natürlich mache ich einfach nur was falsch beim Anbinden. Kann ja nich sein, dass es bei Einem geht, beim Anderen nich.
    Dateien
    • SandboxForm1.zip

      (110,17 kB, 4 mal heruntergeladen, zuletzt: )
    Kann das Build eh nicht starten da Artwie gesagt kein Member von dtbase ist. Die Exception ist quasi in Entwicklungszeit^^
    Bei .Shown ists auch dasselbe
    Oder willst du mir sagen bei dir gibts keine Fehlermeldung?

    Off-Topic: Was heißt es das Exceptions unterdrückt werden? Der Code kann doch nicht einfach trotzdem laufen?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Jau das funktioniert.

    Ich hab zwischenzeitlich herausgefunden, dass es mit einer definierten typisierten DataRow geht.
    Aber wusste gar nicht das (hier z.b.) t eine DataRow ist und keine Table, mich hats so gewundert weil ich da mit den Function(x) -Syntax Erfolg hatte und hier nicht.

    Jetzt ist mir auch klar warum view eine Collection wird. In der LINQ Syntax gibts soviele kleine Dinge erstmal zu entdecken, bevor man es richtig nutzen kann.
    Danke

    PS:
    Ich habe gelesen LINQ wird nicht in der Definitionszeile ausgeführt, sondern erst beim Aufruf eines potentiellen Resultats, sprich:

    VB.NET-Quellcode

    1. Dim view = From t In DS1.dtbase Where t.Art = 1 Select t 'Hier (*) wird nicht gefiltert
    2. Dim a as String = view(0).Art ' Sondern erst hier (**)
    3. Dim b as String = view(0).Gattung 'Heißt das (z.b hier):

    Die Anfrage (*) wird bei jedem Abruf neu ausgeführt, wenn man sie nicht zwischenspeichert?
    Oder reicht (**) als einmaliger Anstoß? Gülte dasgleiche für view(1).Art etc.?

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Haudruferzappeltnoch schrieb:

    Aber wusste gar nicht das (hier z.b.) t eine DataRow ist und keine Table
    sowas ist eiglich einfach herauszufinden: Video-Tut: Welchen Datentyp hat das Objekt?
    Tatsächlich muss man da nichtmal was rausfinden, sondern man weiss, dass eine typDataTable eine Auflistung von typDataRows ist.
    Und Linq funzt immer auf dieselbe Tour: Hat man eine Auflistung kann man mit Linq diese kleinen Funktiönchen drauf anwenden.
    Wobei Argument des Funktiönchens ist immer das einzelne Auflistungs-Element.

    Ergo: bei einer dtbaseDataTable ists die einzelne dtbaseRow.



    Haudruferzappeltnoch schrieb:

    Die Anfrage (*) wird bei jedem Abruf neu ausgeführt, wenn man sie nicht zwischenspeichert?
    Mal wieder nicht präzise formuliert - was meinst du mit "Anfrage zwischenspeichern"?
    Die Anfrage (Query) ist doch zwischengespeichert - ist ja an die Variable view zugewiesen.
    Wenn du aber das Ergebnis der Query meinst, was nicht zwischengespeichert wird, dann hast du recht.

    Haudruferzappeltnoch schrieb:


    Oder reicht (**) als einmaliger Anstoß? Gülte dasgleiche für view(1).Art etc.?
    Nein, "einmaliges Anstossen" - was immer du damit meinst - wird nicht angewendet.
    Eine Query wird ausgeführt, wenn das, oder die, oder eines der Ergebniss(e) abgerufen werden.

    Hier noch zwei alternative Formulierungen:

    VB.NET-Quellcode

    1. Dim view = From t In DS1.dtbase Where t.Art = 1 ' wenn man das t-Objekt insgesamt selektiert kann man den Select-Abschnitt auch weglassen
    2. Dim view = DS1.dtbase.Where(Function(t) t.Art = 1)

    Das heißt so führe ich zig Querys durch 8| ?

    VB.NET-Quellcode

    1. Dim view = From t In DS1.dtbase Where t.Art = 1 Select t
    2. Dim a as String = view(0).Art
    3. Dim b as String = view(1).Art
    4. Dim c as String = view(2).Art
    5. ...
    6. Dim d as String = view(0).Gattung
    7. Dim e as String = view(1).Gattung
    8. Dim f as String = view(2).Gattung
    9. ...usw.

    und so nicht?

    VB.NET-Quellcode

    1. Dim view = From t In DS1.dtbase Where t.Art = 1 Select t
    2. Dim zwischenspeicher as EnumerableRowCollection(Of dtbaseRow) = view
    3. Dim a as String = zwischenspeicher(0).Art
    4. Dim b as String = zwischenspeicher(1).Art
    5. Dim c as String = zwischenspeicher(2).Art
    6. ...
    7. Dim d as String = zwischenspeicher(0).Gattung
    8. Dim e as String = zwischenspeicher(1).Gattung
    9. Dim f as String = zwischenspeicher(2).Gattung
    10. ...usw.
    Doch, so auch.



    Aber so nicht:

    VB.NET-Quellcode

    1. Dim view = DS1.dtbase.Where(Function(t) t.Art = 1).ToArray
    2. Dim a as String = view(0).Art
    3. Dim b as String = view(1).Art
    4. Dim c as String = view(2).Art
    5. ...
    6. Dim d as String = view(0).Gattung
    7. Dim e as String = view(1).Gattung
    8. Dim f as String = view(2).Gattung
    (Preisfrage: Welchen Datentyp hat nu view?)

    Haudruferzappeltnoch schrieb:

    Liegt das daran, dass eine Collection dynamisch befüllbar ist und ein Array nicht?
    Das liegt an .ToArray(). To Array ist englisch und bedeutet "zu Array" - die Methode macht also aus dem IEnumerable(Of T) ein T().

    Haudruferzappeltnoch schrieb:

    Oder anders gefragt wie sehe ich welches Kommando eine Abfrage letztlich durchzieht.
    Äh - watt? "Kommando durchziehen" - hä?



    Ach - nochn Tipp: Nenn die Dinge so, wie was sie sind. Eine Query ist eine Query - sie ist kein view.
    gute Benamung ist nicht schwer:

    VB.NET-Quellcode

    1. Dim rows = DS1.dtbase.Where(Function(t) t.Art = 1).ToArray
    Da weiss man, dass rows mehrere sind, und dass es DataRows sind.
    Wenn jetzt die Tabelle auch noch einen sinnvollen Namen hätte - das wäre vielleicht mal toll!
    Vielleicht soll sie ja Tiere darstellen - reime ich mir so zusammen, wegen Spalten wie Art und Gattung.
    Also wenn die Tabelle selbst so hiesse wie was sie darstellt, dann könnte man noch viel sinniger benamen:

    VB.NET-Quellcode

    1. Dim tiere = DS1.Tier.Where(Function(t) t.Art = 1).ToArray

    Warum ist Art eiglich eine Nummer? IN meiner Welt hat eine Art eine Bezeichnung, also bei mir gäbs eine Tabelle Art, mit ID und Name.
    Also das geht schon wieder in Richtung Datenmodellierung.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Also in ein Array umwandeln bedeutet, dass das Resultat der Abfrage gespeichert wird, es folgen also keine weiteren Abfragen aus der Verwendung der Array-Inhalte.

    Bei der Definition der Abfrage Dim view = ... holt er noch kein Resultat (das nenn ich Abfrage nicht durchziehen^^), bei Zuweisung einer Ergebniszeile ...= view(0).Art und bei .ToArray schon (Das nenn ich durchgezogene Abfrage, weil jetzt liegen die einzelnen Ergebniselemente bereit).

    Wenn ich widerum die ganze Collection zuweise ..=view wird kein Resultat eingeholt.

    Vielleicht machts ja auch kein Unterschied ob ich viele Einzeiler als Ergebnis abrufe oder einmal alle Zeilen.
    Falls doch, wäre es ja ganz relevant zu wissen, welche Befehle richtig "rechnen" (im Sinne Ergebnisse der Abfrage finden) müssen und welche nicht.

    Haudruferzappeltnoch schrieb:

    Also in ein Array umwandeln bedeutet, dass das Resultat der Abfrage gespeichert wird...
    So ungefähr.
    Genauer: Die Resultate der Abfrage (ich nenne es lieber "Query", weil Linq ist Akronym für "language integrated Query") werden in ein Array gefüllt.

    Haudruferzappeltnoch schrieb:

    ... es folgen also keine weiteren Abfragen aus der Verwendung der Array-Inhalte.
    natürlich nicht - ein Array ist ja keine Query.

    Haudruferzappeltnoch schrieb:

    Wenn ich widerum die ganze Collection zuweise ..=view wird kein Resultat eingeholt.
    Was meinst du mit "Collection"?
    Dein view ist eine Query, keine Collection.
    Ein Array könnte man hingegen als Collection bezeichnen - üblicherweise nennt man den allgemeinen Begriff dafür aber "Auflistung" (wohl um Verwechslungen zu vermeiden, weil es gibt auch eine Klasse Collection).
    Es gibt noch weitere Auflistungs-Typen: List(Of T), ObservableCollection(Of T), ... Guckma hier: Grundlagen: Fachbegriffe

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    IN meiner Welt hat eine Art eine Bezeichnung

    Ja das liegt daran, dass ich mir nur eine Beispieltabelle gemacht habe zum Ausprobieren. Um den Inhalt hab ich mich weniger gekümmert^^

    Also view ist EnumerableRowCollection(Of T), eine EnumerableRowCollection ist also immer eine Query und nicht die Ergebnisse einer Query wie z.B. das Array.
    Huch - eine EnumerableRowCollection(Of T)!

    Tja, tut mir leid - ich fürchte es gibt keine wasserdichte Möglichkeit, anhand des Datentyps zu bestimmen, ob ein IEnumerable(Of T) eine Query ist, oder nur eine Auflistung.
    (EnumerableRowCollection(Of T) ist übrigens auch eine IEnumerable(Of T), denn es erbt davon)

    Und Ich schulde noch eine Definition von was ich als "Query" bezeichne: Query ist ein IEnumerable(Of T) mit Lazy Evaluation.
    Lazy Evaluation bedeutet, dass die Elemente nicht fertig in einem Speicherbereich geparkt sind, sondern sie werden sukzessive evaluiert erst in dem Moment, wo ein Element angefordert wird (lazy eben).
    Lazy Evaluation hat Vor- und Nachteile, und ist nur mit IEnumerable(Of T) möglich.
    Ein (geringer) Vorteil ist, dass Speicherplatz gespart wird.
    Ein weiterer ist, wenn in grossen Datenmengen mit komplizierter Element-Evaluierung gesucht wird, dass man beim Finden die Evaluierung abbrechen kann, und so sehr viele Elemente erst garnet evaluiert werden müssen.
    Nachteil ist, wenn man von der Query mehrmals Ergebnissse abruft, dass dann jedesmal die aufwändige Evaluierung ausgeführt wird ("durchziehen" in Haudrauf-Sprech).
    Aber man muss ja nur .ToArray an eine Query anhängen, und schon ists ein normales Array mit den Array-typischen ausgezeichneten Zugriffszeiten.
    Man kann auch in andere Auflistungs-Typen umwandeln, .ToList(), oder .ToDictionary()