MiniProfiler是一款針對.NET, Ruby, Go and Node.js的性能分析的輕量級程序。可以對一個頁面本身,及該頁面通過直接引用、Ajax、Iframe形式訪問的其它頁面進行監控,監控內容包括數據庫內容,並可以顯示數據庫訪問的SQL(支持EF、EF CodeFirst等 )。並且以很友好的方式展現在頁面上。
MiniProfiler官網:http://miniprofiler.com/
MiniProfiler的一個特別有用的功能是它與數據庫框架的集成。除了.NET原生的 DbConnection類,MiniProfiler還內置了對實體框架(Entity Framework)以及LINQ to SQL、RavenDb和MongoDB的支持。任何執行的Step都會包括當時查詢的次數和所花費的時間。為了檢測常見的錯誤,如N+1反模式,profiler將檢測僅有參數值存在差異的多個查詢。
MiniProfiler是以Apache License V2.0協議發布的,你可以在NuGet找到。
過去一直使用Sqlserver Profiler,但是發現實在是太痛苦了,你不得不進行新建、過濾、清除、關閉等操作,而且過濾篩選往往比較難以控制。后來發現MiniProfiler工具非常好用。
同類監控工具有NanoProfiler,下載地址:https://github.com/ef-labs/nanoprofiler/issues/1
Demo開發環境
- Win10
- VS2013
准備工作
新建MVC項目WebAppEF,使用Northwind數據庫。
1、先安裝MiniProfiler
2、安裝MiniProfiler.MVC4
3、安裝MiniProfiler.EF
4、修改Global.asax文件
我這里只需要在開發環境使用SQL性能監控,所以使用了#if DEBUG,因為生產環境,我們一般是采用release模式。同時,MiniProfiler還支持授權,這里不做介紹。
using StackExchange.Profiling; using StackExchange.Profiling.EntityFramework6; using System; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace WebAppEF { publicclassMvcApplication : System.Web.HttpApplication { protectedvoid Application_Start() { #if DEBUG MiniProfilerEF6.Initialize(); #endif AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } protectedvoid Application_BeginRequest(Object source, EventArgs e) { #if DEBUG MiniProfiler.Start(); #endif } protectedvoid Application_EndRequest() { #if DEBUG MiniProfiler.Stop(); #endif } } }
5、在你的布局頁(_Layout)中,比如以下這種結構,修改_Layout.cshtml
@using StackExchange.Profiling; <head> .. </head> <body> ... @MiniProfiler.RenderIncludes() </body>
6、修改配置文件Web.config
<system.webServer> <handlers> <add name="MiniProfiler" path="mini-profiler-resources/*" verb="*" type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified" preCondition="integratedMode"/> </handlers> </system.webServer>
7、添加控制器測試代碼
public ActionResult Index() { // create the entity object using (NorthwindEntities mobjentity = new NorthwindEntities()) { ViewBag.SelectCustomer = mobjentity.Customers.Select(x => x.City == "Delhi").ToList(); } var profiler = MiniProfiler.Current; using (profiler.Step("查詢Customers的數據")) { using (NorthwindEntities entity = new NorthwindEntities()) { ViewBag.data = entity.Customers.ToList(); } } return View(); }
8、按F5調試運行
說明:標記為duplicate的部分,代表在一次請求當中,重復執行了查詢,可以進行優化。通過Step可以對獨立的sql塊進行標記。
常見錯誤
1、The Entity Framework was already using a DbConfiguration instance before an attempt was made to add an 'Loaded' event handler. 'Loaded' event handlers can only be added as part of application start up before the Entity Framework is used. See http://go.microsoft.com/fwlink/?LinkId=260883 for more information.
分析:錯誤提示的大意是在試圖為DbConfiguration 實例加Loaded事件之前已經在其它地方使用了這個實例了
解決方案:把MiniProfiler.EF6.Initialize()在放在Database.SetInitializer<WebAppEF.Models.NorthwindEntities>(null); 之前。
2、Could not load file or assembly 'MiniProfiler, Version=3.0.11.0, Culture=neutral, PublicKeyToken=b44f9351044011a3' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
分析:找不到MiniProfiler程序集或者它的依賴項。程序集定義和引用不匹配。
解決方案:查看Web.config中是否存在如下配置節點
<dependentAssembly> <assemblyIdentityname="MiniProfiler"publicKeyToken="b44f9351044011a3"culture="neutral" /> <bindingRedirectoldVersion="0.0.0.0-3.2.0.157"newVersion="3.2.0.157" /> </dependentAssembly>
如果不存在則添加,如果存在,則檢查MiniProfiler版本號和packages.config中的版本號是否一致,如果不一致就要對版本號進行修改。
參考: