Glimpse HUD 和 SQL 选项卡中的数据库查询计数之间存在差异

Discrepancy between DB Query count in Glimpse HUD & SQL Tab

此问题涉及 Glimpse.MVC3 和 Glimpse.EF5 包。我正在尝试调试旧 MVC3 站点上的性能问题。根据 Glimpse 的 HUD,一个特定的 GET 请求总共有 12 个查询 28ms - 但是当我展开打开主面板,然后单击 SQL 选项卡 ,它说在 只有 6 个查询总共 10.41 毫秒。顶部的计数都是 6,当我计算它列出的查询时,有 6。当我看到编写的代码时,这也很有意义。 (无论哪种方式,我都可以看到太多被延迟加载,需要修复。)

Glimpse 没有任何迹象表明相同的 6 个查询被执行了两次(当我看到 HUD 显示的数字是面板显示的两倍时,我的大脑就这么想了)。

此外,HUD 显示 0 Ajax 请求,但历史部分实际上显示 1(这绝对准确).

知道为什么会有差异吗? (请记住,我更关心与查询的差异。)



编辑 - JSON 根据要求来自文件:

glimpse_sql:
{
  data:
  {
    "SQL Statistics":
    [
      {
        connectionCount: 6
        queryCount: 6
        transactionCount: 0
        queryExecutionTime: 6.91
        connectionOpenTime: 116.08
      }
    ]
    Queries:
    [
      [
        Commands per Connection
        Duration
      ]

hud:
  {
    sql:
    {
      data:
      {
        queryCount: 12
        connectionCount: 12
        transactionCount: 0
        queryExecutionTime: 41.87
        connectionOpenTime: 242.96
      }
      name: sql
    }

编辑 2 - 查询

"Queries":[["Commands per Connection","Duration"],

[[["Transaction Start","Ordinal","Command","Parameters","Records","Duration","Offset","Async","Transaction End","Errors"],[null,"1","SELECT TOP (2) \r\n[Extent1].[TrxnID] AS [TrxnID], \r\n[Extent1].[StartTime] AS [StartTime], \r\n[Extent1].[Lane] AS [Lane], \r\n[Extent1].[EmployeeID] AS [EmployeeID], \r\n[Extent1].[OptionsCompleted] AS [OptionsCompleted], \r\n[Extent1].[StoreID] AS [StoreID], \r\n[Extent1].[NoVehicleTireCheck] AS [NoVehicleTireCheck], \r\nFROM [Activity].[Trxn] AS [Extent1]\r\nWHERE [Extent1].[TrxnID] = 353 /* @p__linq__0 */",[["Name","Value","Type","Size"],["@p__linq__0",353,"Int32",0]],1,1.12,76.67,false,null,null,""]],5.85],

[[["Transaction Start","Ordinal","Command","Parameters","Records","Duration","Offset","Async","Transaction End","Errors"],[null,"1","SELECT \r\n[Extent1].[TrxnID] AS [TrxnID], \r\n[Extent1].[CustomerID] AS [CustomerID], \r\n[Extent1].[FirstName] AS [FirstName], \r\n[Extent1].[LastName] AS [LastName], \r\n[Extent1].[RewardAccountID] AS [RewardAccountID], \r\n[Extent1].[CustomerEmail] AS [CustomerEmail], \r\n[Extent1].[HomePhone] AS [HomePhone]\r\nFROM [Activity].[Trxn_Customers] AS [Extent1]\r\nWHERE [Extent1].[TrxnID] = 353 /* @EntityKeyValue1 */",[["Name","Value","Type","Size"],["@EntityKeyValue1",353,"Int32",0]],0,1.18,102.7,false,null,null,""]],21.7],

[[["Transaction Start","Ordinal","Command","Parameters","Records","Duration","Offset","Async","Transaction End","Errors"],[null,"1","SELECT \r\n[Extent1].[TrxnID] AS [TrxnID], \r\n[Extent1].[VehicleID] AS [VehicleID], \r\n[Extent1].[VehicleVIN] AS [VehicleVIN], \r\n[Extent1].[VehicleOdometer] AS [VehicleOdometer], \r\n[Extent1].[VehicleEngineID] AS [VehicleEngineID], \r\n[Extent1].[VehicleMakeID] AS [VehicleMakeID], \r\n[Extent1].[ModelYear] AS [ModelYear]\r\nFROM [Activity].[Trxn_Vehicles] AS [Extent1]\r\nWHERE [Extent1].[TrxnID] = 353 /* @EntityKeyValue1 */",[["Name","Value","Type","Size"],["@EntityKeyValue1",353,"Int32",0]],0,1.26,2301.56,false,null,null,""]],27.72],

[[["Transaction Start","Ordinal","Command","Parameters","Records","Duration","Offset","Async","Transaction End","Errors"],[null,"1","SELECT \r\n[Extent1].[TrxnID] AS [TrxnID], \r\n[Extent1].[SecondaryVehicleID] AS [SecondaryVehicleID], \r\n[Extent1].[SecondaryVehicleVIN] AS [SecondaryVehicleVIN], \r\n[Extent1].[SecondaryVehicleTypeID] AS [SecondaryVehicleTypeID], \r\n FROM [Activity].[Trxn_SecondaryVehicles] AS [Extent1]\r\n WHERE [Extent1].[TrxnID] = 353 /* @EntityKeyValue1 */",[["Name","Value","Type","Size"],["@EntityKeyValue1",353,"Int32",0]],0,1.15,2325.95,false,null,null,""]],23.15],

[[["Transaction Start","Ordinal","Command","Parameters","Records","Duration","Offset","Async","Transaction End","Errors"],[null,"1","SELECT \r\n[Extent1].[TrxnServiceID] AS [TrxnServiceID], \r\n[Extent1].[TrxnID] AS [TrxnID], \r\n[Extent1].[PackageID] AS [PackageID], \r\n[Extent1].[PartID] AS [PartID], \r\n[Extent1].[Qty] AS [Qty]\r\nFROM [Activity].[Trxn_Services] AS [Extent1]\r\nWHERE [Extent1].[TrxnID] = 353 /* @EntityKeyValue1 */",[["Name","Value","Type","Size"],["@EntityKeyValue1",353,"Int32",0]],0,1.02,2342.92,false,null,null,""]],15.74],

[[["Transaction Start","Ordinal","Command","Parameters","Records","Duration","Offset","Async","Transaction End","Errors"],[null,"1","SELECT \r\n[Extent1].[TrxnNoteID] AS [TrxnNoteID], \r\n[Extent1].[TrxnID] AS [TrxnID], \r\n[Extent1].[NoteText] AS [NoteText], \r\n[Extent1].[NoteNumber] AS [NoteNumber], \r\n[Extent1].[SendToInvoice] AS [SendToInvoice]\r\nFROM [Activity].[Trxn_Notes] AS [Extent1]\r\nWHERE [Extent1].[TrxnID] = 353 /* @EntityKeyValue1 */",[["Name","Value","Type","Size"],["@EntityKeyValue1",353,"Int32",0]],0,1.19,4689.34,false,null,null,""]],21.92]

]},"name":"SQL"}

好吧,我明白了。但首先,请查看出现问题所需的确切使用场景。

使用场景
仅当您执行以下操作时才会出现此问题:
一种。为上下文启用延迟加载。
b.将您的 EF 模型直接传递给视图,不要使用视图模型(这不是好的做法 无论如何 ,但这是遗留代码正在做的事情)。

我学到了什么
1) 事实证明,HUD 显示的查询数量较高是正确的 - SQL Server Profiler 揭示了这一点。

2) Glimpse 本身似乎触发了额外的查询。当我打开“元数据”选项卡时,它似乎以某种方式访问​​导航属性,导致延迟加载。如果我关闭 Glimpse,或保持 Glimpse 开启但禁用元数据选项卡,则不会发生额外查询。

解释
我花了一段时间才弄清楚这一点,因为我搜索了代码并建立了一个测试场景来隔离问题。在其中,我检索了一条记录,之后没有触及任何导航属性。通过它,我确定我的代码中没有访问导航属性来导致它 - 但是应用程序仍然生成所有这些额外的查询,我对 where 他们是从哪里来的。

我最终放弃了解决这个问题,禁用了上下文的延迟加载(这可以防止额外的调用),但随后 NullReferenceException 被抛到一个导航属性上。这个特定的导航 属性 我已经迫不及待地加载了,所以我更加困惑为什么它是空的。在那个导航 属性 上设置一个断点,我发现它被击中 两次 - 一次当我调用它时(那时它不为空),然后是第二次time after 我的 View/Razor 代码编译完成,它又莫名其妙地被击中了。 调用堆栈似乎指向它来自 Glimpse。果然,我能够继续处理异常并加载页面(没有错误或丢失数据),但 Glimpse 有一个引用 属性 的元数据选项卡中显示的错误。我将两个和两个放在一起并尝试转动 Glimpse on/off 然后禁用元数据选项卡。在任何一种情况下,额外的查询都会停止,并且在启用 Glimpse 但禁用元数据选项卡的情况下,HUD 和 SQL 选项卡查询计数匹配。问题已解决。

现在澄清一下,我并不是说这是我提到的性能问题的原因 - 当性能问题开始出现时甚至没有安装 Glimpse,据我所知,Glimpse 在发布模式下默认处于关闭状态反正。性能问题是由代码中发生的一些明显的延迟加载引起的。 但是,当我修复了代码中发生的延迟加载时,HUD 选项卡中的查询计数并没有减少很多,性能也没有t 增加 - 现在这是有道理的。 对于我从代码中删除的每个延迟加载的查询,Glimpse 通过访问“元数据”选项卡的导航属性在幕后生成一个查询。



底部 Line/TLDR: 禁用 Glimpse Metadata 选项卡可以解决我的问题。在调试模式下减少了查询次数并提高了性能,并且 Glimpse 的 HUD 与其 SQL 选项卡之间的查询次数没有差异。