2016-11-10 12 views
4

完了までに約10秒かかるEF4クエリがあります。クエリはあまり複雑ではありませんが、関連するテーブルが多数含まれているため、時間がかかります。私はそれをスピードアップしようとしています。なぜこのEFクエリに時間がかかりますか?

元のクエリは、この(わかりやすくするために短縮)のようになります...

var supportTickets = ctx.SupportTickets 
    .Include(s => s.System.Customer.Country) 
    .Include(s => s.System.Site.Address.Country) 
    // other includes omitted 
    .OrderByDescending(s => s.ID) 
    .ToList(); 
var ticketsList = supportTickets 
    .Select(CreateSupportTicketListOverview) 
    .ToList(); 

CreateSupportTicketListOverview()は、エンティティを受け取り、それに基づいてDTOを返すメソッドです。その短縮版は次のようになります...

これは、約10秒で4000回の結果しか返しません。 SQL Server Profilerは、クエリが約6.6秒かかることを示しています。生成されたSQLをコピーしてそれを単独で実行すると、約2秒しかかかりません。これは私を混乱させます。それ自身で動くとなぜそれはずっと速いのですか?エンティティを作成するのに必要な時間はデータベースクエリに含まれませんでしたか?それがあった場合、残りの時間はどのように過ごしたのですか?

私は、完全なエンティティではなく、データベースから必要なデータだけをトラッキングして取り除くことで、これを改善しようとしました。改訂されたコードは、これが完了するまでに約15秒かかりました、私の驚きに

var tickets = ((SalesTrackerCRMEntities) getContext()).SupportTickets 
     .AsNoTracking() 
     .Include(s => s.System.Customer.Country) 
     .Include(s => s.System.Site.Address.Country) 
     .OrderByDescending(s => s.ID) 
     .Select(t => new { 
     SystemNumber = t.System != null ? t.System.DHRNumber : "", t.ID, 
     CustomerName = t.System != null && t.System.Customer != null ? t.System.Customer.Name : "", 
     SiteName = t.Site != null ? t.Site.SiteName : "", 
     Status = t.Status != null ? t.Status.Description : "", 
     // other stuff omitted 
     }) 
     .AsEnumerable(); 
    var tickets1 =tickets 
     .Select(t => new SupportTicketListOverview { 
     ID = t.ID, 
     SystemNumber = t.SystemNumber, 
     CustomerName = t.CustomerName, 
     ShortSummary = t.ShortSummary, 
     SiteName = t.SiteName, 
     Status = t.Status, 
     // other stuff omitted 
     }) 
     .ToList(); 

...この(再び明確にするために短縮)のように見えます。プロファイラを見ると、データベースクエリ自体は約0.7秒で、すなわち元のクエリよりもが速くでしたが、EFクエリ全体では、が50%になりました。

私は完全に混乱しています。私はいくつかの検索をしましたが、私が見つけたすべてのアドバイスは、私がすでにやっていることのためのものでした。たとえば、this blog postは、EFパフォーマンスを向上させる7つの方法を示します。これには、リポジトリパターンを使用しないこと(実際に彼がここで何を意味していたかはわかりませんでした。どのように行うかしないかの例は示していませんでした)、ページングを使用しない私たちは少なくとも新しいクエリで)、遅延ロードをオフにしています(既にオフになっていました)、トラッキングをオフにして(既に行っていました)、テーブルのインデックスを使用しています。最後のヒントは、クエリの数を減らすことでした。関連するすべてのデータが必要なので、ここでどのようにこれを行うことができるかわかりません。

要約すると、元のデータベースクエリは6.6秒かかり、全体的なEFクエリは10秒かかります。修正されたクエリは、データベース部分では0.7秒、全体的なEFクエリでは15秒かかります。これらはすべてあまりにも長いです。

誰かが質問をスピードアップする方法をアドバイスできますか?ありがとう

+0

データベースサーバーは別の地域にありますか?私の紺碧のWebアプリケーションが米国地域と私のデータベース(誤って)ブラジル地域でホストされていたとき、私は(類似した)類似の問題を抱えていました。 – Developer

+1

アクセスしているテーブルが適切にインデックスされていますか?まともなクエリを組み立てるという点でEF4はうんざりです。 –

+2

http://stackoverflow.com/questions/2876616/returning-ienumerablet-vs-iqueryablet – Hackerman

答えて

0

使用しているSQL Serverのバージョンは? 2016年であれば、クエリストア(https://msdn.microsoft.com/en-us/library/dn817826.aspx)を有効にして、EF4クエリによって実行されているt-sqlクエリを見つけることができます。古いバージョンの場合は、EF4クエリを実行している間に、この(http://blog.sqlauthority.com/2009/01/07/sql-server-find-currently-running-query-t-sql/)を使用してクエリテキストを検索し、それをサーバーに対して実行して計画/欠落インデックス/などを分析する理由を確認します。

+0

ありがとうございましたが、元の質問で言いましたが、SQLをSSMSにコピーすると、実行には2秒しかかかりませんので、問題はありません。 –

関連する問題