【问题标题】:How to find low performance code in my t-sql procedure如何在我的 t-sql 过程中找到低性能代码
【发布时间】:2014-03-30 08:16:00
【问题描述】:

我有一些表现出低性能的嵌套程序。为了找到瓶颈,我在 t-sql 代码中插入了一些调试标记,以测量我怀疑性能低下的代码块的性能。这个调试标记看起来像:

select @start_point = GETDATE() -- start measuring point
---
open @session_license_fee_cur -- suspected chunk of code
---
select @end_point = GETDATE()-- end measuring point
select @duration = datediff(ms, @start_point, @end_point)
select @log_info_total = 'Opening cursor license_fee (bills_supp_create_license_fee) (@class_id = ' + cast(@class_id as nvarchar) + ')';

exec bills_supp_save_calculation_log @duration, @log_info_total, @house_id, @account_id, @log_level -- procedure for creating log (simple insert into log table pes_bl_bills_calculation_log_total) 

运行程序后,我从pes_bl_bills_calculation_log_total 表运行查询以查找性能最低的代码。看起来是这样的

    set @session_license_fee_cur =  cursor static for 
    select activity_id
            , addendum_id
            , service_id
            , active_from
            , active_to
    from dbo.bills_supp_get_activate_license_fee_for_sessions_by_house(@active_from, @active_to, @house_id)

select @start_point = GETDATE()
---
open @session_license_fee_cur
---
select @end_point = GETDATE()
select @duration = datediff(ms, @start_point, @end_point)
select @log_info_total = 'Opening cursor license_fee (bills_supp_create_license_fee) (@class_id = ' + cast(@class_id as nvarchar) + ')';
exec bills_supp_save_calculation_log @duration, @log_info_total, @house_id, @account_id, @log_level

换句话说,打开 @session_license_fee_cur 工作非常缓慢(大约 501980 毫秒)。

我正在尝试在 SQL Server Management Studio 中使用给定参数运行这段代码,以查看查询计划并尝试对其进行优化。我是这样运行的

declare @active_from date = '01.03.2014'
declare @active_to date = '01.04.2014'
declare @house_id integer = 11927
        select activity_id
                , addendum_id
                , service_id
                , active_from
                , active_to
        from dbo.bills_supp_get_activate_license_fee_for_sessions_by_house(@active_from, @active_to, @house_id)

但它的工作速度非常快(在大约 0(零)秒内返回 3000 条记录)。 在程序中打开光标有什么区别

open @session_license_fee_cur

并在 SQL Server Management Studio 中运行它?

declare @active_from date = '01.03.2014'
declare @active_to date = '01.04.2014'
declare @house_id integer = 11927
        select activity_id
                , addendum_id
                , service_id
                , active_from
                , active_to
        from dbo.bills_supp_get_activate_license_fee_for_sessions_by_house(@active_from, @active_to, @house_id)

我的瓶颈在哪里?

【问题讨论】:

  • 主要差异是引擎不需要处理光标。您可以尝试使用 FAST_FORWARD 提示该游标,但通常最好的方法是避免使用游标。顺便说一句,使用 sysdatetime() 而不是 getdate()
  • 谢谢琼。看来我发现了问题。函数 bills_supp_get_activate_license_fee_for_sessions_by_house 中的子查询有一个导致降级的完整扫描查询。但有一件事我没有得到。为什么这个在 SQL Management Studio 中没有游标的查询的工作时间约为 0 秒,但在查询中它的工作时间超过 5 分钟。为什么会有这样的差异?
  • 你必须看到生成的查询计划,这可以给你一些线索(包括关于全表扫描)。也许游标正在分配大量内存/临时数据库。尝试监控 CPU、内存和 IO,看看游标声明做错了什么。

标签: sql-server performance tsql


【解决方案1】:

从读取 IO 的角度找出前 5 个昂贵的查询

http://www.sqlservercentral.com/scripts/DMVs/102045/

【讨论】:

  • 谢谢。但是前 5 个查询没有显示我的日志中显示的内容。从我的日志的角度来看,它向我展示了运行速度足够快的程序。也许我错了,但前两个“读取扩展”查询在“总物理读取”列中显示了我 3811。不幸的是,我不知道它是否太多,但我的直觉告诉我它不是那么多。我说的对吗?
猜你喜欢
  • 2016-05-20
  • 1970-01-01
  • 2011-10-12
  • 2022-12-07
  • 2012-03-04
  • 2023-04-09
  • 2015-11-11
  • 2019-10-06
  • 2016-01-30
相关资源
最近更新 更多