0

我编写了一个相当简单的存储过程,它接受一些数据,选择一个值,插入几条记录,然后返回该值。但是在我们的生产环境中执行时间过长,我最终可能希望它一天运行几十万次,即使我们只运行它说 30000 次,它也会对其他进程产生不利影响。

我首先查看查询并在 where 子句中使用的日期字段上添加索引。然后我运行 SQL Server Profiler——将结果输入 Tuning Advisor 并实施它提出的索引建议。过去,我看到该工具需要非常丑陋的索引,但这次它只需要一个有意义的添加,所以我添加了它。这些步骤中的每一个都有帮助。但是还是太慢了。

很容易发现第一个查询是阻塞,而不是几乎瞬时的两个插入。所以这就是我当时所拥有的,包括子查询运行时:

--all combined, this typically takes in the range of 1200-1500 ms but occasionally spikes up to ~2200 ms
select coalesce(
    (   
        --when the following is run, this takes ~690 ms
        select MIN(maxes.imbsn) 
        from (
            --when the following is run without the higher limiting scopes, this takes ~3600 ms
            select imbsn, MAX(assignmentDate) maxAD 
            from imbsnAssignments 
            group by imbsn
            ) maxes
        where datediff(d, maxes.maxAD, GETDATE()) > 90
    )
    ,
    (
        --this is rarely executed but takes ~0 ms when it is
        select max(imbsn)+1 from imbsnAssignments
    )
)

基于那些时间,似乎合并正在搞砸事情(我想如果我曾经弄清楚如何阅读它,我可以用执行计划来验证它,但我没有 - 计划在很大程度上仍然存在对我可怜的大脑来说是不透明的)。为了摆脱合并,我将查询更改为:

--this runs ~480-700 ms
select MIN(maxes.imbsn) 
from (
    select imbsn, MAX(assignmentDate) maxAD 
    from imbsnAssignments 
    group by imbsn
        union
    select max(imbsn)+1, getDate() 
    from imbsnAssignments
    ) maxes
where datediff(d, maxes.maxAD, GETDATE()) > 90

这是一个很大的改进。但它仍然很慢。

我确认 Profiler-Tuning Advisor 仍然不希望我在来这里询问您之前进行任何更改。我认为这让我有两种方法:1)保持基本算法,但从中挤出更高的效率,或者 2)通过我不知道但一种显而易见的方法切换到一些更聪明的方法来获得相同的基本效果致那些嗅出我在这里从事某种反模式的大脑袋。

提前感谢您的时间和关注!


我不确定这些附加信息的预期格式是什么,但我会试一试。表格是:

CREATE TABLE [dbo].[imbsnAssignments](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [imbsn] [int] NOT NULL,
    [assignmentDate] [date] NOT NULL,
    [jobCode] [varchar](10) NOT NULL,
    [name] [varchar](45) NOT NULL,
    [a1] [varchar](45) NOT NULL,
    [a2] [varchar](45) NOT NULL,
    [a3] [varchar](45) NOT NULL,
    [a4] [varchar](45) NOT NULL,
    [city] [varchar](40) NOT NULL,
    [state] [char](10) NOT NULL,
    [zip] [varchar](10) NOT NULL,
    [batchIdent] [varchar](256) NOT NULL,
 CONSTRAINT [PK_imbsnAssignments] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

我怀疑这不是显示索引的“正确”方式,但是:

 TableName            IndexName                                          IndexType

 imbsnAssignments     PK_imbsnAssignments                                CLUSTERED
 imbsnAssignments     IX_imbsnAssignments_assignmentDate                 NONCLUSTERED
 imbsnAssignments     _dta_index_imbsnAssignments_36_149575571__K2_3     NONCLUSTERED

执行计划:

  |--Stream Aggregate(DEFINE:([Expr1013]=MIN([partialagg1018])))
       |--Concatenation
            |--Stream Aggregate(DEFINE:([partialagg1018]=MIN([IMB].[dbo].[imbsnAssignments].[imbsn])))
            |    |--Filter(WHERE:([Expr1003]<dateadd(day,(-90),getdate())))
            |         |--Stream Aggregate(GROUP BY:([IMB].[dbo].[imbsnAssignments].[imbsn]) DEFINE:([Expr1003]=MAX([IMB].[dbo].[imbsnAssignments].[assignmentDate])))
            |              |--Index Scan(OBJECT:([IMB].[dbo].[imbsnAssignments].[_dta_index_imbsnAssignments_36_149575571__K2_3]), ORDERED FORWARD)
            |--Stream Aggregate(DEFINE:([partialagg1018]=MIN([Expr1009])))
                 |--Compute Scalar(DEFINE:([Expr1009]=[Expr1008]+(1)))
                      |--Stream Aggregate(DEFINE:([Expr1008]=MAX([IMB].[dbo].[imbsnAssignments].[imbsn])))
                           |--Top(TOP EXPRESSION:((1)))
                                |--Index Scan(OBJECT:([IMB].[dbo].[imbsnAssignments].[_dta_index_imbsnAssignments_36_149575571__K2_3]), ORDERED BACKWARD)
4

1 回答 1

1

首先,我建议在第二个示例中将您的 where 子句更接近实际表,并且我会检查执行计划以查看它在做什么,也许计算 90 天前检查它,而不是每个 maxAD 值的 DATEDIFF。并且只需将联合更改为联合所有,这样它就不必检查数据集之间的唯一性。

select MIN(maxes.imbsn) 
from (
    select imbsn, MAX(assignmentDate) maxAD 
    from imbsnAssignments 
    group by imbsn
    having max(assignmentdate) < dateadd(-90, d, GETDATE())
        union all
    select max(imbsn)+1, getDate() 
    from imbsnAssignments
) maxes
于 2013-05-06T19:49:49.003 回答