Leistung von LINQ-Abfragen gegen die SQL-Entsprechung

8

Ich habe gerade eine Diskussion mit jemandem über die Leistung von LINQ-Abfragen gegen das SQL-Äquivalent.

Hat irgendjemand irgendwelche wissenschaftlichen Tests dazu gemacht?

Falls nicht, helfen mir Einzelberichte darüber, wo Sie LINQ durch eine SQL-Abfrage aus Performance-Gründen ersetzen mussten.

    
Amanda Nicholls 06.07.2011, 15:00
quelle

9 Antworten

8

Ich habe eine etwas andere Einstellung dazu; Beim Profiling (mit unserem glänzenden Profiler ) haben wir festgestellt, dass LINQ (in diesem Fall SQL) aktiv war ein vernünftiger Job, der TSQL für grundlegende Abfragen generiert, und der Vorgang lief sehr schnell auf dem DB-Server (0.5ms etc) - jedoch dauerte die tatsächliche Abfrageoperation VIEL länger (wie 20ms + für die gleiche 0.5ms-Abfrage in einigen Fällen) . Wo war die Zeit? Sie könnten denken "Query Translation", aber nein; Wir haben auch eine Menge von ExecuteQuery<T> code (d. h. wo Sie die TSQL von Hand schreiben) und dies tat genau das gleiche . Es stellte sich heraus, dass zwischen dem Materializer und der Identity Map sehr viel Zeit verloren ging.

Also; Wir haben unseren eigenen Materializer geschrieben, der ziemlich hübsch war - ein Ersatz für ExecuteQuery - und wurde daher dapper geboren .

Auf der LINQ-Seite ist es normalerweise OK, TSQL für einfache -Abfragen zu generieren, aber für alles, was komplex ist, vertraue ich normalerweise handcodierten TSQL. Um einen Fall als Beispiel zu nehmen, hatte ich eine komplexe Abfrage mit Gruppen, Überspringungen und Takes. Es hat nicht gut funktioniert. Wenn ich es manuell mit ROW_NUMBER () usw. geschrieben habe, haben die gleichen Ergebnisse 4% des "stats IO" und der Gesamtzeit eingenommen.

Meine aktuelle Meinung zu LINQ ist, dass die ORM-Tools die Mutation leicht machen, aber für query verwende ich dapper . Das ist ironisch, da das Q in LINQ "query" ist.

    
Marc Gravell 06.07.2011 15:33
quelle
6

LINQ wie in LINQ2SQL oder EF muss einen verallgemeinerten Regelsatz haben, wie die LINQ-Abfragen in SQL konvertiert werden können, und damit wird eine Abstraktionsebene eingeführt. Diese Abstraktion führt manchmal zu weniger als optimalen Aussagen. Wenn Sie Ihre SQL-Anweisungen von Hand schreiben, können Sie sie für Ihren speziellen Fall optimieren.
Dies führt zu der Schlussfolgerung, dass die Geschwindigkeit von SQL insbesondere in komplexen Szenarien mit höherer Wahrscheinlichkeit schneller ist. Dies bedeutet jedoch nicht, dass jede LINQ-Abfrage langsamer ist als ihre SQL-Entsprechung.
Meine Erfahrung mit EF 1 in Kombination mit Oracle unterstützt dies.

    
Daniel Hilgarth 06.07.2011 15:04
quelle
4

Eines der offensichtlichsten Beispiele, bei denen die SQL-Abfrage besser ist, ist das Aktualisieren / Löschen der Stapelverarbeitung. In LINQ-To-SQL ist keine Funktion integriert, um mehrere Aktualisierungen oder Löschungen zu verarbeiten, außer dass die Datensätze nacheinander verarbeitet werden, wodurch für jeden Datensatz individuelle Abfragen generiert werden.

%Vor%

Im allgemeinen Fall ist LINQ optimiert, um sehr effiziente Abfragen zu generieren, und kann manchmal sogar bessere Abfragen erzeugen als die intuitive Art, es mit SQL zu schreiben. Es wird jedoch immer Ausnahmen geben, bei denen die LINQ-zu-SQL-Anweisungen nicht so effizient sind wie eine SQL-Abfrage, die von Hand geschrieben werden kann.

    
mellamokb 06.07.2011 15:04
quelle
2

LinqToSql ist eine Ebene über ADO.Net. Wenn Sie also ADO.Net mit Sql-Abfragen verwenden, sind Sie "schneller" als LinqToSql (indem Sie nicht die zusätzlichen Dinge tun, die LinqToSql tut).

Dasselbe Argument (wenn Performance das einzige Kriterium ist) kann für .Net- und für Maschinencode verwendet werden. .Net IL ist letztlich JIT'ed zu Machine und wenn Sie nur Maschine an erster Stelle geschrieben haben, würden Sie schneller sein.

Hier ein paar Szenarien, wo es darauf ankommt:

  • Wenn Ihre Abfragen niedrig sind und große Datenmengen zur Materialisierung zurückgegeben werden, benötigt LinqToSql viel mehr Zeit als ein roher SQL. Auf der anderen Seite haben Sie Kundeninstanzen anstelle von DataRows.
  • Wenn Ihre Abfragen sehr dynamisch sind, sodass Sie nie denselben SQL-Text zweimal ausgeben, entstehen immer Übersetzungskosten. Sql-Abfragen werden schneller (vor allem, wenn Sie die Konstruktion des SQL-Textes nicht zählen).

Hier ein paar Szenarien, in denen es einfach nichts ausmacht:

  • Wenn Ihre Abfragen Datenbank-IO-stark sind (Berichtsstil), werden Sie die zusätzlichen clientseitigen CPU-Kosten der LinqToSql-Abstraktion nicht bemerken.
  • Wenn Ihre Abfragen wiederholend sind (dieselbe Abfrage mit anderen Parametern), können Sie einen Großteil der Kosten für die Abstraktion von LinqToSql durch die Verwendung von CompiledQuery mindern. & lt; - Ich denke, die meisten Systeme passen zu diesem Szenario.
Amy B 06.07.2011 16:14
quelle
1

LINQ soll am Ende optimierte SQL-Abfragen erzeugen, sodass Sie in den meisten Fällen mit LINQ sicher sind. Es gibt Ausnahmen, bei denen es besser ist, die SQL-Abfrage selbst zu optimieren, aber dies sind Ausnahmen.

    
Adrian Carneiro 06.07.2011 15:03
quelle
0

Bitte überprüfen Sie andere Fragen: LINQ-to-SQL vs gespeicherte Prozeduren?

Linq ist meiner Meinung nach gut genug für fast jeden Aspekt. Für einige seltene Fälle, wenn Sie sehr gut in SQL sind und wirklich die Leistung verbessern wollen, dann gehen Sie stattdessen für raw sql.

    
longbkit 06.07.2011 15:08
quelle
0

Wenn Sie eine LINQ-Abfrage ausführen, generiert LINQ T-SQL-Code zum Ausführen Ihrer Abfrage. Sie können den SQL Server Profiler ausführen, um eine Vorstellung davon zu erhalten, wie die Abfrage aussieht. Ich habe es in der Vergangenheit gemacht und das T-SQL generiert sieht ziemlich sauber aus.

Ich kann nicht direkt von der Leistung sprechen, da ich keine Zahlen ausgeführt habe, aber eine Sache, die ich gesehen habe, ist, dass Sie, wenn Sie keine Zeilenversionsspalte in Ihrer Tabelle für die LINQ-Abfragen verwenden, jede Spalte erhalten in der Tabelle, die in der WHERE-Klausel enthalten ist, was auf diese Weise als Teil der integrierten optimistischen Parallelitätsprüfung von LINQ geschieht. Durch die Verwendung der Spalte rowversion kann LINQ nur diese Spalte für diese Überprüfung verwenden und sorgt für saubereres und leistungsfähigeres T-SQL.

    
Zannjaminderson 06.07.2011 15:05
quelle
0

Nach meiner Erfahrung ist das Problem mit EF4.1 oder LINQtoSQL nicht LINQ, sondern der Coder.

Entwickler können im Allgemeinen keine effizienten Abfragen programmieren oder einen effizienten und skalierbaren Datenbankzugriff programmieren (d. h. sie kennen VB oder C # gut, aber nicht SQL) und dies zeigt, wie sie eine Abfrage erstellen. An diesem Punkt spielt es keine Rolle, ob sie LINQ verwenden oder nicht.

Wo das wirklich auftaucht, ist, wenn Anwendungen in der Entwicklung gut funktionieren (die dev-Datenbank hat ein paar 100.000 Datenzeilen), aber in der Produktion schlecht funktioniert (Millionen von Datenzeilen). Entwickler weisen sofort darauf hin, dass es in der Entwicklung gut funktioniert hat, daher muss etwas mit der Datenbank nicht stimmen und nicht mit ihrem Code. So beginnen Kriege zwischen Entwicklern und DBAs.

Obwohl ich LINQ wirklich mag, ist es oft besser, wenn Sie Abfragen in Stored Procs verschieben, damit Sie Ihren Datenzugriff optimieren und optimieren können, ohne einen kompletten Dev-Test-QA-Release-Zyklus für Ihre Anwendung für jeden Minor durchführen zu müssen aktualisieren.

    
Steve G 07.07.2011 15:33
quelle
0

In diesem Jahr habe ich einen Fehlerbericht über die Performance von Linq2Sql beim Einfügen vieler Datensätze in einen einzigen Transaktionssatz eingereicht. Jede einzelne Einfügung dauerte zunehmend länger und länger, da Linq2Sql die Beziehungen überprüfen musste - was der DB-Server ohnehin prüfen würde.

Sie können den Fehlerbericht unter Ссылка

Klicken Sie auf Show Details und ich habe einige Performance-Nummern eingefügt.

Interessanterweise war Microsofts Antwort, dass sie nicht vorhatten, die Performance von Linq2Sql zu verbessern und dass ich ADO.Net verwenden sollte, was ich bereits beschlossen hatte.

Mein Fazit an dieser Stelle ist, dass ich Linq2Sql für Abfragen liebe, aber nicht für Einfügungen oder Aktualisierungen. Ich mag auch die Tatsache, dass Linq2Sql die Datensätze von meinen Fremdschlüsseln für mich füllt, ohne separate Abfragen zu codieren.

Wie bei komplizierten Abfragen - ich verwende etwa 50% mit Linq2Sql und etwa 50% gespeicherten Prozeduren. Ich mache nie Inline-SQL, weil ich lieber stark typisierte Methoden verwende. Für einfache Abfragen schlägt die Einfachheit von Linq2Sql 100% der Zeit auf ADO.Net.

    
Robert Tanenbaum 07.07.2011 18:44
quelle

Tags und Links