Ich wurde gebeten, die Ursache einer schlecht funktionierenden Abfrage in unserer Datenbank zu untersuchen. Ich habe festgestellt, dass es von einer LINQ-Anweisung generiert wurde und es zum Quellcode zurückverfolgt und in linqpad geladen wurde. In Linqpad habe ich das generierte SQL angezeigt (siehe unten). Wie Sie sehen, ist der erste Teil der WHERE-Klausel unnötig und verlangsamt die Abfrage erheblich, indem er Indizes vermeidet. Es sollte nur auf den DocumentStorageId Schlüssel abfragen und das war's. Es gibt keinen Sinn für die Anweisung IN(), jede Zeile in der Produkttabelle hat einen dieser Werte und ist nicht null. Irgendwelche Ideen, wie ich meine linq-Anweisung ändern kann, so dass die ID zuerst und von Indizes getroffen wird?Warum generiert diese Entitätsframework-LINQ-Abfrage eine langsame Where-Klausel?
void Main()
{
var uow = new UnitOfWork(this);
var repo = new Repository<Product>(this,uow);
var documentStorageId = new Guid("473BAE6B-A1A1-49BE-9FD5-AB6B870A82B1");
var result = repo.Queryable()
.Where(x => x.DocumentStorageId == documentStorageId)
.FirstOrDefault();
result.Dump();
}
generiert SQL Ausgang:
SELECT
[Extent1].[AColumn],
[Extent1].[BColumn]
FROM [dbo].[Product] AS [Extent1]
WHERE
([Extent1].[ProductType] IN
(N'Type1',N'Type2',N'Type3',N'Type4',N'Type5',N'Type6'))
AND ([Extent1].[DocumentStorageId] = @p__linq__0)
EDIT: weiter zu klären, das Modell erstellt wird mit Code zuerst. Produkt ist eine Basisklasse. Es gibt 6 abgeleitete Produkttypen (Typ1, Typ2 usw.). ProductType ist die Diskriminatorspalte. Es sieht so aus, als würde EF versuchen, jede mögliche Produktart einzubeziehen, aber warum? Das Einschließen von all ist gleichbedeutend damit, kein bestimmtes zu spezifizieren, und die IN() -Klausel lässt die Abfrage langsam ablaufen.
Ich bin mir nicht sicher, warum das 'IN' hier nur mit einem einfachen' .Where (x => x.Id == Id) verwendet wird. Sind Sie sicher, dass es irgendwo keine zusätzlichen Einschränkungen gibt? –
Ja, ich stimme travis zu, dies wird nicht durch den Code verursacht, den Sie gepostet haben, können Sie bitte Ihren Modell- und Modellkonfigurationscode posten. –
@Travis Wie ich in der Frage sagte, wenn ich die Top-Anweisung in LinqPad und klicken Sie auf "Show Generated SQL" klicken, bekomme ich den Boden. Ich weiß, es macht keinen Sinn und ist nicht optimal, deshalb poste ich diese Frage. – redwards510