2009-08-10 7 views
0

Ich führe die folgende Abfrage auf meiner Datenbank, die eine SQL-Abfrage generiert, ich weiß, gibt 0 Ergebnisse und wenn in Sql Management Studio ausgeführt dauert weniger als eine Sekunde, um zurückzukehren.Warum dauert es so lange, bis eine leere Ergebnismenge in linqtosql angezeigt wird?

var query = (from item in db.Table 
      where item.Field == FieldValue // Field is not the primary key but is indexed 
      from other in item.Associated_Table 
      select other.Table); 
List<Table> result = query.ToList(); 

Die Associated_Table ist eine Join-Tabelle, die Elemente in Tabelle mit anderen Elementen in Tabelle verknüpft. Die resultierende Abfrage sieht wie folgt aus:

declare @p0 as int 

SELECT 
    [t2].[ItemCategoryID], 
    [t2].[InventoryItemID], 
    [t2].[SiteID], 
    [t2].[ItemDescription], 
    [t2].[AverageMonthlyUsage], 
    [t2].[ReorderLevel], 
    [t2].[ReorderQuantity], 
    [t2].[OtherItemDetails], 
    [t2].[Price] AS [IntPrice], 
    [t2].[Ordinal], 
    [t2].[IsBase] AS [IntIsBase], 
    [t2].[Units], 
    [t2].[ProfitCenterID] AS [IntProfitCenterID], 
    [t2].[AccountID], 
    [t2].[PLU] AS [IntPLU], 
    [t2].[BarCode], 
    [t2].[DisplayName], 
    [t2].[ExtraServiceAmount] AS [IntExtraServiceAmount], 
    [t2].[IsSearchable], 
    [t2].[Terminated], 
    [t2].[PdxServiceKey], 
    [t2].[IsOpenPrice], 
    [t2].[ItemPromotionCategoryID] 
FROM 
    [dbo].[Inventory.Item] AS [t0] 
CROSS JOIN 
    [dbo].[Inventory.ItemExtraAssignment] AS [t1] 
INNER JOIN 
    [dbo].[Inventory.Item] AS [t2] 
     ON [t2].[InventoryItemID] = [t1].[ExtraInventoryItemID] 
WHERE 
    ([t0].[PLU] = @p0) AND 
    ([t1].[InventoryItemID] = [t0].[InventoryItemID]) 

In Management Studio diese Abfrage läuft unter einer Sekunde und liefert 0 Ergebnisse. Warum dauert es 2 Sekunden, um die 2 Zeilen von C# auszuführen, die dieselbe Abfrage ausführen? Mir ist klar, dass LinqToSql einen gewissen Aufwand für die Analyse der Objekte benötigt, aber da keine Objekte zurückgegeben werden, sollte es keine Arbeit zu erledigen haben.

Gibt es eine Optimierung, die ich vermisse; oder vielleicht Einige Einstellungen im dbml oder SQL Server selbst, die geändert werden müssen?

Antwort

1

Linq den Ausdrucksbaum zur Laufzeit übersetzen muss. Im Allgemeinen wird der Ausdrucksbaum als Teil der Abfrageauswertung übersetzt. Bei vielen Abfragen können Sie dies jedoch mithilfe von CompiledQuery separat durchführen.

//do this once 
Func<CustomDataContext, int, List<Table>> queryFunc = 
System.Data.Linq.CompiledQuery.Compile<CustomDataAccess, int, List<Table>> 
((dc, i) => 
    from item in dc.Table 
    where item.Field == i 
    from other in item.Associated_Table 
    select other.Table).ToList() 
); 
    //time this 
List<Table> result = queryFunc(db, FieldValue); 
+0

Ich hatte das gerade selbst gefunden und kam hierher zurück, um meine eigene Antwort einzureichen. Dieser Artikel war eine große Hilfe zum Erlernen kompilierter Abfragen: http://msmvps.com/blogs/omar/archive/2008/10/27/solving-common-problems-with-compiled-queries-in-linq-to-sql -für-hohe-Nachfrage-asp-net-websites.aspx – Mykroft

0

dauert es noch 2 Sekunden, um die Abfrage ein zweites Mal auszuführen? LINQ to SQL kann einige Zeit in Anspruch nehmen, um seine Abhängigkeiten zu laden und beim ersten Mal verschiedene Initialisierungsbits auszuführen, aber danach schnell.

Darüber hinaus schlage ich vor, dass Sie sich die SQL Server-Protokolle ansehen und sehen, wie lange die Abfrage in der Datenbank dauerte, wenn sie von LINQ aus ausgeführt wurde.

+0

Es dauert jedes Mal etwa 1,6 bis 1,8 Sekunden. Ich muss mir die Server-Logs anschauen. – Mykroft

+0

Laut SQL Server Profiler dauert diese Abfrage weniger als eine Sekunde zu verarbeiten. – Mykroft

1

Das Verhalten, das Sie beschreiben, weist auf einen zwischengespeicherten Abfrageplan hin, der aufgrund veralteter Statistiken, versetzter Indizes oder falschem Parameter-Sniffing nicht mehr geeignet ist.

Versuchen Sie, die Indizes für die beteiligten Tabellen neu zu erstellen oder zumindest Ihre Statistiken zu aktualisieren.

[SSMS emittiert Präambel-, dass eine erneute Kompilierung jedes Mal zwingt]

+0

Neuaufbau der Indizes und Aktualisierung der Statistiken scheint keine Auswirkungen zu haben. – Mykroft

+0

@Mykroft: können Sie den Ausführungsplan für die langsamen und normalen Abfragen erfassen. –

Verwandte Themen