So optimieren Sie Entity Framework-Abfragen

entity-framework mysql performance

Frage

Ich verwende Linq-To-Entities, um eine Abfrage auszuführen, die nur 947 Zeilen zurückgibt, aber nur 18 Sekunden dauert. Ich habe ein "ToTraceString" gemacht, um die zugrunde liegende SQL-Instanz herauszuholen, und dasselbe direkt in der Datenbank ausgeführt und das gleiche Timing erhalten.

Ich habe den Tuning-Ratgeber verwendet und ein paar Indizes erstellt, allerdings mit geringer Wirkung.

Wenn Sie sich den Ausführungsplan für Abfragen ansehen, gibt es einige verschachtelte Schleifen, die 95% der Zeit beanspruchen, aber diese arbeiten bereits an den Indizes.

Hat jemand eine Idee, wie man eine Optimierung in die EF-Abfrage erzwingen kann?

EDIT: Zusätzliche Informationen

Ein grundlegendes ER-Diagramm für die drei Tabellen sieht wie folgt aus:

People >----People_Event_Link ----< Events
P_ID        P_ID                    E_ID
            E_ID

Die linq, die ich verwende, ist so konzipiert, dass sie alle Ereignisse für eine bestimmte Person zurückbekommt (unter Verwendung der P_ID):

        var query = from ev in genesisContext.Events
                    join pe in genesisContext.People_Event_Link
                    on ev equals pe.Event
                    where pe.P_ID == key
                    select ev;
        return query;

Hier ist die generierte SQL (Deep Breath!):

SELECT 
1 AS [C1], 
[Extent1].[E_ID] AS [E_ID], 
[Extent1].[E_START_DATE] AS [E_START_DATE], 
[Extent1].[E_END_DATE] AS [E_END_DATE], 
[Extent1].[E_COMMENTS] AS [E_COMMENTS], 
[Extent1].[E_DATE_ADDED] AS [E_DATE_ADDED], 
[Extent1].[E_RECORDED_BY] AS [E_RECORDED_BY], 
[Extent1].[E_DATE_UPDATED] AS [E_DATE_UPDATED], 
[Extent1].[E_UPDATED_BY] AS [E_UPDATED_BY], 
[Extent1].[ET_ID] AS [ET_ID], 
[Extent1].[L_ID] AS [L_ID]
FROM  [dbo].[Events] AS [Extent1]
INNER JOIN [dbo].[People_Event_Link] AS [Extent2] ON  EXISTS (SELECT 
    1 AS [C1]
    FROM    ( SELECT 1 AS X ) AS [SingleRowTable1]
    LEFT OUTER JOIN  (SELECT 
        [Extent3].[E_ID] AS [E_ID]
        FROM [dbo].[Events] AS [Extent3]
        WHERE [Extent2].[E_ID] = [Extent3].[E_ID] ) AS [Project1] ON 1 = 1
    LEFT OUTER JOIN  (SELECT 
        [Extent4].[E_ID] AS [E_ID]
        FROM [dbo].[Events] AS [Extent4]
        WHERE [Extent2].[E_ID] = [Extent4].[E_ID] ) AS [Project2] ON 1 = 1
    WHERE ([Extent1].[E_ID] = [Project1].[E_ID]) OR (([Extent1].[E_ID] IS NULL) AND ([Project2].[E_ID] IS NULL))
)
WHERE [Extent2].[P_ID] = 291

Akzeptierte Antwort

Ja. Schreiben Sie die LINQ-Abfrage neu. Die meisten LINQ to Entities-Abfragen können auf viele verschiedene Arten geschrieben werden und werden unterschiedlich in SQL übersetzt. Da Sie weder LINQ noch SQL oder den Abfrageplan anzeigen, kann ich dazu nichts sagen.

Sie sind jedoch klug, die SQL direkt auszuführen. Die Abfragekompilierung kann auch Zeit in Anspruch nehmen, aber Sie haben dies ausgeschlossen, indem Sie die SQL-Datenbank für die gesamte gemessene Zeit ermitteln.

Versuchen:

    var query = from pe in genesisContext.People_Event_Link
                where pe.P_ID == key
                from ev in pe.Event // presuming one to many
                select ev;

oder wenn pe.Event eins zu eins ist:

    var query = from pe in genesisContext.People_Event_Link
                where pe.P_ID == key
                select pe.Event;

    return query;

Beliebte Antwort

@Craig Ich konnte Ihre Abfrage nicht zum Laufen bringen, da eine Fehlermeldung angezeigt wurde, dass Type Inference beim Aufruf von SelectMany fehlgeschlagen ist.

Ich habe jedoch Ihren Rat angenommen und bin vom Join zu einem "alten Stil" vor der ANSI-Typabfrage gegangen:

        var query = from pe in genesisContext.People_Event_Link
                    from ev in genesisContext.Events
                    where pe.P_ID == key && pe.Event == ev
                    select ev;

Welches ziemlich anständige sql produziert!



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum