Ef Zeitüberschreitung bei Linq-Abfragen, aber dieselben Abfragen unter SSMS weniger als 1 Sekunde
uerst habe ich versucht,ARITHABORT OFF
auf SSMS ist es noch weniger als 1 Sekunde.
Ich verwende EntityFrameWork: 6.1.3 und die Azure Sql S1-Schicht (Ich werde es mit Schicht 3 versuchen und Sie informieren, wenn sich etwas ändert.)
Ich verwende EF Profiler, um SQL von Linux zu generieren. Ich habe alle von mir freigegebenen Linqs abgefragt, sie sind alle weniger als 1 Sekunde auf SSMS.
Ich habe 3 Millionen Einträge in AuditLog Table. Ein Kunde mit der ID 3 verfügt über 170.000 Datensätze, der andere Kunde mit der ID 35 verfügt über 125 Datensätze. Ich werde den Code minimieren.
AuditLog Model:
public class AuditLog
{
public long? CustomerId { get; set; }
[ForeignKey("CustomerId")]
public virtual CustomerSummary Customer { get; set; }
[Required]
[Index]
public DateTime CreatedDate { get; set; }
}
Erste Abfrage:
if (customer != null)
{
var customerId = customer.Id;
var result= Dbset.Where(x => x.CustomerId == customerId).OrderByDescending(x => x.CreatedDate).Skip(0).Take(25).ToList();
}
Wenn ich es mit einem Kunden mit 170.000 Zeilen versuche, gibt es eine Ausnahmebedingung. Wenn ich es mit einem Kunden mit 125 Datensätzen versuche, ist das in Ordnung.
Second Query: Das gleiche gilt für das erste, für das ich nur Kunden einbeziehe.
if (customer != null)
{
var customerId = customer.Id;
var result= Dbset.Where(x => x.CustomerId == customerId).OrderByDescending(x => x.CreatedDate).Skip(0).Take(25).Include(x => x.Customer).ToList();
}
Das Ergebnis ist das Gegenteil der ersten Abfrage. Wenn ich es mit einem Kunden mit 170.000 Zeilen versuche, ist das in Ordnung. Wenn ich es mit einem Kunden mit 125 Datensätzen versuche, gibt es eine Zeitüberschreitungsausnahme.
Dritte Abfrage: Es ist das gleiche mit der ersten Abfrage, aber ich stimme mit @ überelong?
on where for customerId.
if (customer != null)
{
long? customerId = customer.Id;
var result= Dbset.Where(x => x.CustomerId == customerId).OrderByDescending(x => x.CreatedDate).Skip(0).Take(25).ToList();
}
Das Ergebnis ist das Gegenteil der ersten Abfrage. Wenn ich es mit einem Kunden mit 170.000 Zeilen versuche, ist das in Ordnung. Wenn ich es mit einem Kunden mit 125 Datensätzen versuche, gibt es eine Zeitüberschreitungsausnahme.
Vierte Abfrage: Es ist das gleiche mit der zweiten Abfrage, aber ich stimme mit @ überelong?
on where for customerId.
if (customer != null)
{
long? customerId = customer.Id;
var result= Dbset.Where(x => x.CustomerId == customerId).OrderByDescending(x => x.CreatedDate).Skip(0).Take(25).Include(x => x.Customer).ToList();
}
Das Ergebnis ist das Gegenteil der zweiten Abfrage. Wenn ich es mit einem Kunden mit 170.000 Zeilen versuche, gibt es eine Zeitüberschreitungsausnahme. Wenn ich es mit einem Kunden mit 125 Datensätzen versuche, ist das in Ordnung.
Ich bin wirklich verwirrt. Warum innerer Join oder Ändern des Match-Parameters auflong?
ändern sich die Ergebnisse? Und warum laufen alle Abfragen unter 1 sec auf SSMS und geben Fehler auf ef linq?
Error
{System.Data.SqlClient.SqlException (0x80131904): Zeitüberschreitung abgelaufen. Das Zeitlimit, das vor Abschluss des Vorgangs verstrichen ist, oder der Server reagiert nicht. ---> System.ComponentModel.Win32Exception (0x80004005): Zeitüberschreitung der Warteoperation bei System.Data.SqlClient.SqlConnection.OnError (SqlException-Ausnahme, Boolean breakConnection, Action`1 wrapCloseInAction)
Update (19/04/2016):
NachIvan Stoev Vorschlag zu Kommentaren.
Haben Sie versucht (nur für Testzwecke) mit Hardcoded 3 und 35 anstelle voncustomerId
variable?
Ich habe keinen Fehler erhalten und die Abfragen sind wie bei SSMS am schnellsten.
Update (20.04.2016): Das eigentliche Problem istParameter Sniffing. Wenn ich Parameter in nullable einfügte oder änderte, habe ich tatsächlich andere Abfragen und andere Abfragepläne erstellt. Ich habe einige Pläne mit Kunden erstellt, die 125 Datensätze haben, und die anderen mit Kunden, die 170.000 Datensätze für diese 4 Abfragen haben. Deshalb habe ich unterschiedliche Ergebnisse erzielt.