You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

定位引发Azure SQL高CPU占用的重复查询调用来源

追踪Azure SQL高CPU查询的来源及优化建议

一、应用层注入来源标识(最直接方案)

  • 在应用的数据库操作入口(如页面初始化、接口方法),执行会话上下文设置,传入来源标识:
    EXEC sp_set_session_context N'CallerSource', N'ProductListPage';
    
  • SQL端可通过SESSION_CONTEXT(N'CallerSource')获取该标识,结合后续的追踪工具,直接关联到调用页面/接口。

二、Azure SQL内置工具追踪

1. 扩展事件(Extended Events)

  • 创建针对目标查询的事件会话,捕获sql_statement_completed事件,同时勾选session_context、client_app_name、client_hostname等字段。
  • 设置过滤条件匹配目标查询的特征文本(如SELECT clmns.name AS [Name]),只捕获该查询的执行记录,从中提取来源信息。

2. Query Store

  • 在Query Store中通过查询文本匹配找到目标查询,查看其执行历史中的session_id。
  • 关联sys.dm_exec_sessions视图获取program_name、host_name等信息;若已注入会话上下文,可通过sys.dm_exec_session_context查询CallerSource的值。

3. DMVs实时查询

  • 先通过sys.dm_exec_query_stats定位目标查询的sql_handle:
    SELECT sql_handle, execution_count
    FROM sys.dm_exec_query_stats
    CROSS APPLY sys.dm_exec_sql_text(sql_handle)
    WHERE text LIKE '%SELECT clmns.name AS [Name]%'
    
  • 再关联会话视图获取来源标识:
    SELECT s.session_id, s.program_name, sc.value AS CallerSource
    FROM sys.dm_exec_sessions s
    JOIN sys.dm_exec_session_context sc ON s.session_id = sc.session_id
    WHERE sc.key = N'CallerSource'
    

三、应用层日志拦截

  • 使用AOP框架(如.NET AspectCore、Java Spring AOP)拦截所有数据库操作方法,自动记录调用来源(页面/接口名)、查询文本、参数到应用日志。
  • 若使用ORM(如Entity Framework),可拦截DbCommand执行事件,在查询文本前添加来源注释(如-- Source: CheckoutPage),SQL端追踪记录会直接显示来源。

四、临时应急方案

  • 找到应用中生成该查询的代码位置,给不同调用处的查询添加唯一注释标识:
    -- From: UserProfilePage
    SELECT clmns.name AS [Name], ...
    
  • 通过SQL执行日志或扩展事件,根据注释区分调用来源。

五、针对该查询的优化建议

  • 该查询是读取系统表获取列元数据,大概率是ORM框架自动生成的元数据查询。开启ORM的元数据缓存(如EF的ModelCacheKey),避免重复执行。
  • 若无法缓存,可将查询结果缓存到应用层(如Redis、内存缓存),减少对SQL的直接调用。

内容的提问来源于stack exchange,提问作者Core IP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 09:55:39