MS Sql-Server超时

时间:2011-05-02 15:17:44

标签: sql sql-server

我们在MS Sql Server中有以下存储过程。它由具有相同参数的作业在每天下午5点运行。有些日子它因超时错误而失败,有时它运行正常。我试图重现错误,但它太随机了。

我知道有很多代码可以粘贴一个问题,但我尝试过很多不同的东西,但仍无法确定它可能发生的位置。

另外,我知道我也在调用其他一些函数,但是暂时忽略它们。如果此存储过程没有任何错误,那么我也会发布一些其他函数。

如果您需要任何其他信息,请与我们联系。感谢。

编辑:对于下面的评论员,我不希望任何人解开这个代码。我只是在寻找可能导致问题的建议。感谢那些已经给我一些建议的人。

USE [economy]
GO
/****** Object:  StoredProcedure [dbo].[ec_mailcomponent_dismaldigest_html]    Script Date: 05/02/2011 11:09:47 ******/
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ec_mailcomponent_dismaldigest_html]
    @sid        varchar(50), 
    @frequency  int,
    @listID     int=1
AS

SET NOCOUNT ON

--//////////////////////////////////////////////////
--//  Declare Variables
--//////////////////////////////////////////////////
DECLARE 
    @release        varchar(50),
    @location       varchar(255),
    @country        varchar(50),
    @intro          varchar(100),
    @value      varchar(40),
    @strDayName         varchar(255),
    @release_date       smalldatetime,
    @prior_release_date smalldatetime,
    @title          varchar(255),
    @summary        char(300),
    @iAid           int,
    @text           varchar(8000),
    @sFrequency     varchar(20),
    @release_id     varchar(50),
    @sFirstTake     varchar(800),
    @sLink          varchar(255),
    @sTrackLink     varchar(255),
    @sLinkId        varchar(50),
    @sCorpLink      varchar(255),
    @tempDate       varchar(100),
    @ref_per        varchar(30),
    @freq           int,
    @watch_country  varchar(40),
    @consensus      varchar(30),
    @forecast       varchar(30),
    @ref_date       smalldatetime,
    @iEdition       int,
    @sEdition       varchar(100),
    @iPrevEdition       int,
    @edition        varchar(50),
    @i              INT --int for number of days to go back.  0 for US -1 for Europe


--********************************************
--Create the temp table
--********************************************
SET @iPrevEdition = 0
--CREATE TABLE #return ( return_value text, orderby  int IDENTITY(1,1))
DECLARE @return TABLE ( return_value text, orderby  int IDENTITY(1,1))

--///////////////////////////////////////
--//  Initialize Variables
--///////////////////////////////////////       
SET @prior_release_date = NULL
SET @i=-1
IF ( @listID = 1 )
    SET @edition = '1,2,3,4'
ELSE IF ( @listID = 36 )
    SET @edition = '1'
ELSE IF ( @listID = 37 )
  BEGIN
    SET @edition = '2'
    SET @i =-1
  END
ELSE IF ( @listID = 38 )
    SET @edition = '3'
ELSE IF ( @listID = 39 )
    SET @edition = '4'

IF ( @frequency = 1 ) 
    SET @sFrequency = 'Daily'
ELSE
    SET @sFrequency = 'Weekly'

--///////////////////////////////////////
--//  Determine if it is weekly or daily
--///////////////////////////////////////       
IF ( @frequency = 2 ) 
        DECLARE rstReleases CURSOR FOR SELECT ri.display_title, ri.release_id, ri.geo, rd.data_actual, rd.release_date, rd.abstract, rd.reference_date, rd.data_ec_forecast, rd.data_consensus, ri.frequency 
        FROM dismal_v8..ds_release_info ri WITH (NOLOCK) 
        INNER JOIN dismal_v8..ds_release_dates rd WITH (NOLOCK) ON ri.release_id=rd.release_id 
        WHERE ri.release_id IN ( SELECT mail_key FROM tps..sh_email_detail WITH (NOLOCK)  WHERE sid = @sid ) AND rd.data_actual IS NOT NULL AND rd.release_date > DATEADD(day, -7, convert(varchar(10), GETDATE(), 101)) AND DATEDIFF(dd, rd.release_date, GETDATE()) >= 0 
        AND (tps.dbo.getDismalReleaseAccess(@sid,ri.release_id,getdate())=1)
        ORDER by left(rd.release_date,11) desc, ri.geo ASC  
ELSE
        DECLARE rstReleases CURSOR FOR SELECT ri.display_title, ri.release_id, ri.geo, rd.data_actual, rd.release_date, rd.abstract, rd.reference_date, 
            rd.data_ec_forecast, rd.data_consensus, ri.frequency 
        FROM dismal_v8..ds_release_info ri WITH (NOLOCK)
            INNER JOIN dismal_v8..ds_release_dates rd WITH (NOLOCK) ON ri.release_id=rd.release_id 
        WHERE ri.release_id IN ( SELECT mail_key FROM tps..sh_email_detail WITH (NOLOCK)  WHERE sid = @sid and list_id=@listID ) 
            AND rd.data_actual IS NOT NULL 
            --AND convert(varchar(10), rd.release_date, 101)=convert(varchar(10), GETDATE(), 101) 
            --Get things done in the last 24hrs
            AND rd.release_date BETWEEN DATEADD(dd,@i,GETDATE()) AND  GETDATE()
            AND (tps.dbo.getDismalReleaseAccess(@sid,ri.release_id,getdate())=1)    
            /*AND rd.release_id in (
                select distinct drd.release_id
                from dismal_v8.dbo.ds_release_dates drd 
                    inner join dismal_v8.dbo.ds_release_edition dre on drd.release_id = dre.release_id
                where dre.edition in (
                    SELECT paramvalue
                    FROM rfa_intranet.dbo.VBSplit(@edition,',')
                )
            )*/ 
        ORDER by left(rd.release_date,11) desc, ri.geo ASC
OPEN rstReleases
FETCH NEXT FROM rstReleases INTO @release, @release_id, @country, @value, @release_date, @sFirstTake, @ref_date, @forecast, @consensus, @freq
WHILE ( @@fetch_status = 0 ) 
    BEGIN
        IF ( DAY(@release_date) <> DAY(@prior_release_date) ) OR ( @prior_release_date IS NULL )                
            BEGIN
                SET @strDayName = DATENAME(dw, @release_date) + '  ' + convert(varchar(10), @release_date, 101)

                IF ( @frequency = 2 )
                    BEGIN
                        SET @tempDate = tps.dbo.FormatDate(@release_date, 'dddd, mmmm d1, yyyy' )
                    END             
                ELSE
                    BEGIN
                        SET @tempDate = 'Economic Indicators Released ' + tps.dbo.FormatDate(@release_date, 'mmmm d1, yyyy' )
                    END
                INSERT INTO @return VALUES( '<font style="font-family: Arial; line-height: 120%;font-size: 12pt; font-weight: bold;color: #000000">' + @tempDate +'</font><br>')
                INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/images/clear.gif" height="15" alt="" /><br>' )

            END

SET @ref_per = tps.dbo.DismalCoverageDateFormat(@ref_date,@freq)


        IF ( @country <> '' )
                    BEGIN   
                        IF @country != @watch_country 
                        BEGIN
                        SET @watch_country = @country
                            IF @country = 'EURO ZONE' OR @country = 'OECD' OR @country = 'WORLD' OR UPPER(@country) = 'NORTH AMERICA'
                                BEGIN
                                    INSERT INTO @return VALUES(  '<b>' + @country +  ' </b><br>' )
                                    INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/images/bar2.gif" height="2" width="600" alt="decorative"><br>' )
                                    INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/images/clear.gif" height="2" alt="" /><br>' )
                                END
                            ELSE
                                BEGIN
                                    INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/dismal/images/flags_ds/flag_i'+ left(@release_id, charindex('_',@release_id)-1) +'.gif" height="16" width="16" border="0" style="margin-bottom:-3px;">&nbsp;&nbsp;<b>' + @country +  ' </b><br>' )
                                    INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/images/bar2.gif" height="2" width="600" alt="decorative"><br>' )
                                    INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/images/clear.gif" height="2" alt="" /><br>' )
                                END
                        END
                    END

                    INSERT INTO @return VALUES(  '<b>' + @release + '</b><br>' )
                    IF ( @release_id != 'usa_fomc_meeting' )
                        INSERT INTO @return VALUES(  '<i>Coverage: ' + @ref_per + '</i><br>' )

                    INSERT INTO @return VALUES(  '<i>Actual: ' + @value + '</i><br>' )
                    INSERT INTO @return VALUES(  '<i>xxx''s xxx: ' + @forecast + '</i><br>' )
                    INSERT INTO @return VALUES(  '<i>Consensus: ' + @consensus + '</i><br>' )
                    INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/images/clear.gif" height="1" alt="" /><br>' )

                INSERT INTO @return VALUES( @sFirstTake + '<br>' )
                INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/images/clear.gif" height="5" alt="" /><br>' )


        SET @sLink = 'http://www.xxx.com/dismal/pro/release.asp?r=' + @release_id
        SET @sCorpLink = 'http://xxx.com/dismal/pro/release.asp?r=' + @release_id


        INSERT INTO @return VALUES(  '<a href="' + @sLink + '">View the entire release</a><br>'  )
        --INSERT INTO @return VALUES(  'View the entire release:&nbsp;&nbsp;<a href="' + @sLink + '">Subscribers</a><br>'  )
        --&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="' + @sCorpLink + '">Site License Users</a><br>'  )       
        INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/images/clear.gif" height="15" alt="" /><br>' )

        SET @prior_release_date = @release_date
        FETCH NEXT FROM rstReleases INTO @release, @release_id, @country, @value, @release_date, @sFirstTake,  @ref_date, @forecast, @consensus, @freq

    END

CLOSE rstReleases
DEALLOCATE rstReleases

--///////////////////////////////////////
--//  Write the thoughts pieces
--///////////////////////////////////////
--Changed to exclude Consumer flow articles.  Added site check (JAG 3/2/05) 
--SELECT TOP 15 title, convert(char(300),summary), content_id FROM dismal_v8..ds_content WHERE DATEDIFF(dy, publish_on, getdate()) < 5  AND status=2  and feature_id=0 ORDER BY publish_on DESC
DECLARE rs_thoughts CURSOR FOR 
        SELECT * FROM (
            SELECT TOP 10 title, convert(char(300),summary) as summary, c.content_id, ei.edition, ei.description
                FROM dismal_v8..ds_content c WITH (NOLOCK) 
            INNER JOIN dismal_v8.dbo.ds_content_site cs WITH (NOLOCK) 
                ON cs.content_id=c.content_id
            INNER JOIN dismal_v8..ds_content_edition ce WITH (NOLOCK)
                ON c.content_id = ce.content_id
            INNER JOIN dismal_v8..ds_edition_info ei WITH (NOLOCK)
                ON ce.edition = ei.edition
                --include blogs type 0 4/19/2011 JAG
            WHERE type IN (0,2) and DATEDIFF(dy, publish_on, getdate()) < 5  AND status=2 AND cs.site = 1 
            AND GETDATE() >= publish_on --Added check to ensure that these articles will be able to be viewed once the user navigates to Dismal's article.asp. JAP 22-Dec-2010
            --Do not add Spotlights to email
            AND c.type <> 8
            ORDER BY publish_on DESC 
        ) as s
        WHERE edition in (SELECT paramvalue FROM rfa_intranet.dbo.VBSplit(@edition,','))
        ORDER BY edition
OPEN rs_thoughts

FETCH NEXT FROM rs_thoughts into @title, @summary, @iAid, @iEdition, @sEdition
IF @@FETCH_STATUS = 0
BEGIN

    INSERT INTO @return VALUES(  '<span style="font-family: Arial; line-height: 120%;font-size: 12pt; font-weight: bold;color: #000000">Recent Commentary From xxx</span><br />' )
    INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/images/clear.gif" height="15" alt="" /><br>' )
    WHILE @@FETCH_STATUS = 0
    BEGIN
        IF (@iPrevEdition <> @iEdition)
        BEGIN
            INSERT INTO @return VALUES(  '<span style="font-family: Arial; line-height: 120%;font-size: 10pt; font-weight: bold;color: #85A053">' + replace(@sEdition, 'Dismal ', '') + '</span><br />' )
            --INSERT INTO @return VALUES(  '<hr>' ) 
            SET @iPrevEdition = @iEdition
        END
        IF left(@title,8) = 'Updated:' AND datepart(dw,CAST(right(@title, len(@title)-8) as smalldatetime)) = 2
            INSERT INTO @return VALUES(  '<b>xxx''s xxx Chartbook - ' + @title +'</b><br>')
        ELSE    
            BEGIN
                INSERT INTO @return VALUES(  '<b>' + @title+'</b><br>' )
                if @summary is not null
                    INSERT INTO @return VALUES(  isNull(@summary, '') +'<br>')
            END
        INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/images/clear.gif" height="5" alt="" /><br>' )

        SET @sLink = 'http://www.xxx.com/dismal/pro/article.asp?cid=' + cast( @iAid as varchar(10) )   
        SET @sCorpLink = 'http://xxx.com/dismal/pro/article.asp?cid=' + cast( @iAid as varchar(10) )   


        --INSERT INTO @return VALUES( 'View the entire article:&nbsp;&nbsp;' )
        INSERT INTO @return VALUES( '<a href="' + @sLink +'">View the entire article</a><br>' )
        --INSERT INTO @return VALUES( '<a href="' + @sLink +'">Individual Subscribers</a>&nbsp;&nbsp;&nbsp;' )
        --INSERT INTO @return VALUES( '<a href="' + @sCorpLink + '">Site License Users</a><br>')

        INSERT INTO @return VALUES(  '<img src="http://www.xxx.com/images/clear.gif" height="15" alt="" /><br>' )


        FETCH NEXT FROM rs_thoughts into @title, @summary, @iAid, @iEdition, @sEdition
    END
END

IF EXISTS(SELECT sid FROM tps..ds_sub_summary_view where sid=@sid AND freq_id=129 AND end_date>getdate() AND getdate()<'2005-06-01')
BEGIN
    INSERT INTO @return VALUES( '<span style="font-family: Arial; line-height: 120%;font-size: 12pt; font-weight: bold;color: #85A053">blah blah blah...</span><br/>' )
    INSERT INTO @return VALUES('blah blah blah...')
    INSERT INTO @return VALUES('blah blah blah...')
    INSERT INTO @return VALUES('blah blah blah...')
    INSERT INTO @return VALUES('blah blah blah...')
    INSERT INTO @return VALUES('blah blah blah...<br/>')
    INSERT INTO @return VALUES('<a href="http://www.xxx.com/dismal/pro_account/dismal_upgrade.asp?tid=29EFA0B8-2033-4B66-9103-BDE1A0C7B874">blah blah blah...</a>')
END

CLOSE rs_thoughts
DEALLOCATE rs_thoughts


--*************************************************
-- Return the values held in the temp table
--*************************************************
SELECT return_value FROM @return ORDER BY orderby ASC

--*************************************************
--Drop the temp table
--*************************************************
--DROP TABLE @return

SET NOCOUNT OFF

4 个答案:

答案 0 :(得分:1)

您可以采取两种方法。

1)增加超时。

2)将游标操作转换为基于Set的SQL语句。你可能会在那里获得显着的性能提升。

答案 1 :(得分:1)

我没有看到任何具体内容 - 但是因为我已经挖掘了游标等等,所以已经有一段时间了。我通常遵循两条经验法则(其他人在过去曾不同意我的观点):

1)光标是邪恶的。只在必要时使用它们,尽可能少。
2)如果您发现自己在SQL存储过程中执行了大量逻辑,请考虑将逻辑迁移到某处的外部代码,以便SQL尽可能少地“处理”。

因人而异。

另外,你有没有对程序进行跟踪(我知道它是随机的,因此可能的答案是'不'),和/或你是否已将资源争用作为可能的答案消除?

答案 2 :(得分:1)

http://wiki.lessthandot.com/index.php/Cursors_and_How_to_Avoid_Them

我根本不需要为此使用游标,它们也不应该是SQL Server中的首选。

可能超时的时间是处理的记录最多的时候。

答案 3 :(得分:0)

我还注意到你正在使用“select ... where ... in”指向另一个数据库中的表。根据我的经验,'in'和'not in'子句与游标一样邪恶(甚至更多),除非您指向的表保证只有少数记录。