Frage

Ich habe derzeit einen Dal in C# mit SQLDATAREADER und gespeicherten Verfahren. Leistung ist wichtig, aber es sollte immer noch wartbar sein ...

Nehmen wir an, es gibt ein Tischrezepte

(recipeID, author, timeNeeded, yummyFactor, ...)

und ein Tischzutaten

(recipeID, name, amount, yummyContributionFactor, ...)

Jetzt möchte ich gerne 200 Rezepte mit ihren Zutaten abfragen. Ich sehe die folgenden Möglichkeiten:

  • Fragen Sie alle Rezepte ab und fragen Sie dann die Zutaten für jedes Rezept.
    Dies würde natürlich zu Maaany -Fragen führen.
  • Fragen Sie alle Rezepte ab und Ihre Zutaten in einer großen Verbindungsliste. Dies führt zu viel nutzlosen Verkehr, da jede Rezeptdaten mehrmals übertragen werden.
  • Fragen Sie alle Rezepte ab, fragen Sie dann alle Zutaten gleichzeitig, indem Sie die Liste der Rezeptionsliste an die Datenbank zurückgeben. Aus Alternativ geben Sie beide Abfragen in einem und zurück und geben Sie mehrere Ergebnisse zurück. Verbinden Sie die Zutaten im Dal wieder mit den Rezepten mit ihrem Rezept.
  • Exotischer Weg: Cursor obwohl alle Rezepte und Rückkehr für jeden Rezept Zwei separate Ergebnisse für Rezept und Zutaten. Gibt es eine Grenze für Ergebnissen?

Für mehr Abwechslung können die Rezepte durch eine Liste von IDs aus dem DAL oder durch eine parametrisierte SQL -Bedingung ausgewählt werden.

Welches hat Ihrer Meinung nach das beste Leistungs-/Messverhältnis?

War es hilfreich?

Lösung

Wenn Sie nur zwei Tabellen anschließen müssen und ein "Zutat" keine große Datenmenge ist, ist es wahrscheinlich, dass die Leistung und die Wartbarkeit eine einzelne zusammengefügte Abfrage sein. Ja, Sie wiederholen einige Daten in den Ergebnissen, aber wenn Sie nicht 100.000 Zeilen haben und das Datenbankserver/das Datenbank -Netzwerk überlastet, ist es zu früh, um zu optimieren.

Die Geschichte ist ein bisschen anders, wenn Sie viele Verbindungsschichten mit einer abnehmenden Kardinalität haben. Zum Beispiel habe ich in einer meiner Apps so etwas wie die folgende:

Event -> EventType -> EventCategory
                   -> EventPriority
                   -> EventSource   -> EventSourceType -> Vendor

Eine solche Abfrage führt zu a von Bedeutung Die Menge an Duplikation ist inakzeptabel, wenn es 100.000 Ereignisse zum Abrufen von 1000 Ereignisarten, möglicherweise 10 Kategorien/Prioritäten, 50 Quellen und 5 Anbieter gibt. In diesem Fall habe ich also eine gespeicherte Prozedur, die mehrere Ergebnissätze zurückgibt:

  • Alle 100K -Events mit Just EventTypeid
  • Die 1000 EventTypes mit CategoryId, PriorityID usw., die für diese Ereignisse gelten
  • Die 10 EventCategories und EventPriorities, die für die oben genannten Eventypes gelten
  • Die 50 Eventources, die die 100K -Ereignisse generierten
  • Und so weiter bekommt man die Idee.

Da die Kardinalität so drastisch sinkt, ist es viel schneller, nur das herunterzuladen, was hier benötigt wird, und ein paar Wörterbücher auf der Client -Seite zu verwenden, um sie zusammenzusetzen (falls dies überhaupt erforderlich ist). In einigen Fällen können die Daten mit niedriger Kardinalität sogar im Speicher zwischengespeichert und nie aus der Datenbank abgerufen werden (außer bei App-Start oder wenn die Daten geändert werden).

Die bestimmenden Faktoren bei der Verwendung eines solchen Ansatzes sind a sehr hohe Anzahl von Ergebnissen und ein Steiler Abnahme der Kardinalität Für die Anschlüsse, mit anderen Worten Fächern. Dies ist eigentlich die Gegenteil der meisten Verwendungen und wahrscheinlich umgekehrt, was Sie hier tun. Wenn Sie "Rezepte" auswählen und sich mit "Zutaten" anschließen, sind Sie es wahrscheinlich Fächern, was diesen Ansatz verschwenderisch machen kann, insbesondere wenn es nur zwei Tische zu verbinden gibt.

Ich stelle es also nur da raus, dass dies eine mögliche Alternative ist wenn Die Leistung wird zu einem Problem in der Straße; Zu diesem Zeitpunkt in Ihrem Design würde ich, bevor Sie reale Leistungsdaten haben, einfach die Route der Verwendung eines einzelnen Verbindungs-Ergebnissatzes gehen.

Andere Tipps

Das beste Leistungs-/Messverhältnis beträgt 42.

Gehen Sie ernsthafter mit der einfachsten Lösung: Abrufen Sie alles mit einer einzelnen Abfrage ab. Optimieren Sie nicht, bevor Sie auf ein Leistungsproblem stoßen. "Frühgeborene Optimierung ist die Wurzel des gesamten Bösen" :) :)

Ein gespeicherter Proc, der 2 Datensätze zurückgibt: "Rezeptheader" und "Rezeptdetails"?

Das würde ich tun, wenn ich die Daten auf einmal auf einmal brauchte. Wenn ich es nicht auf einmal brauche, würde ich immer noch 2 Datensätze erhalten, aber mit weniger Daten.

Wir haben es etwas einfacher gefunden, mit diesem im Kunden damit zu arbeiten als eine große Abfrage, wie Andomar vorschlug, aber seine Antwort ist immer noch sehr gültig.

Ich würde mir das größere Bild ansehen - müssen Sie wirklich Zutaten für 200 Rezepte abrufen? Was passiert, wenn Sie 2.000 haben?

Wenn dies beispielsweise auf einer Webseite liegt, würde ich die 200 Rezepte auflistet (wenn nicht weniger aufgrund von Paging), und wenn der Benutzer auf eine klickte, um die Zutat zu sehen, würde ich die Zutaten aus der Datenbank erhalten.

Wenn dies nicht machbar ist, hätte ich 1 gespeicherte Proc, das einen Datensatz mit 2 Tabellen zurückgibt. Einer mit den Rezepten und die zweite mit der Liste der Zutaten.

"Ich habe gerade einen Dal in C#..." Als Randnotiz möchten Sie sich möglicherweise den Beitrag ansehen: Generieren Sie Datenzugriffsschichtmethoden aus gespeicherten Procs. Es kann Ihnen viel Zeit sparen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top