In dit antwoord concentreer ik me op de oorspronkelijke observatie:de door EF gegenereerde query is traag, maar wanneer dezelfde query in SSMS wordt uitgevoerd, is deze snel.
Een mogelijke verklaring voor dit gedrag is Parameter snuiven .
EF genereert dus een query die weinig parameters heeft. De eerste keer dat u deze query uitvoert, maakt de server een uitvoeringsplan voor deze query met behulp van waarden van parameters die van kracht waren bij de eerste uitvoering. Dat plan is meestal best goed. Maar later voert u dezelfde EF-query uit met andere waarden voor parameters. Het is mogelijk dat voor nieuwe waarden van parameters het eerder gegenereerde plan niet optimaal is en de query traag wordt. De server blijft het vorige plan gebruiken, omdat het nog steeds dezelfde zoekopdracht is, alleen de waarden van parameters zijn anders.
Als u op dit moment de querytekst neemt en deze rechtstreeks in SSMS probeert uit te voeren, zal de server een nieuw uitvoeringsplan maken, omdat het technisch gezien niet dezelfde query is die door de EF-toepassing wordt uitgegeven. Zelfs één tekenverschil is voldoende, elke wijziging in de sessie-instellingen is ook voldoende voor de server om de query als een nieuwe te behandelen. Als gevolg hiervan heeft de server twee plannen voor de schijnbaar dezelfde query in zijn cache. Het eerste "langzame" plan is traag voor de nieuwe waarden van parameters, omdat het oorspronkelijk is gebouwd voor verschillende parameterwaarden. Het tweede "snelle" plan is gebouwd voor de huidige parameterwaarden, dus het is snel.
Het artikel Slow in the Application, Fast in SSMS door Erland Sommarskog legt dit en andere verwante gebieden veel gedetailleerder uit.
Er zijn verschillende manieren om plannen in de cache te verwijderen en de server te dwingen ze opnieuw te genereren. Het wijzigen van de tabel of het wijzigen van de tabelindexen zou het moeten doen - het zou alle plannen moeten weggooien die gerelateerd zijn aan deze tabel, zowel "langzaam" als "snel". Vervolgens voert u de query uit in de EF-toepassing met nieuwe waarden van parameters en krijgt u een nieuw "snel" plan. U voert de query uit in SSMS en krijgt een tweede "snel" plan met nieuwe waarden van parameters. De server genereert nog steeds twee plannen, maar beide plannen zijn nu snel.
Een andere variant is het toevoegen van OPTION(RECOMPILE)
naar de vraag. Met deze optie zou de server het gegenereerde plan niet in zijn cache opslaan. Dus elke keer dat de query wordt uitgevoerd, gebruikt de server werkelijke parameterwaarden om het plan te genereren dat (denkt hij) optimaal zou zijn voor de gegeven parameterwaarden. Het nadeel is een extra overhead van het genereren van plannen.
Let wel, de server kan bij deze optie nog steeds voor een "slecht" abonnement kiezen vanwege bijvoorbeeld verouderde statistieken. Maar het snuiven van parameters zou in ieder geval geen probleem zijn.
Degenen die zich afvragen hoe ze OPTION (RECOMPILE)
. kunnen toevoegen hint voor de vraag die door EF is gegenereerd, bekijk dit antwoord:
https://stackoverflow.com/a/26762756/4116017