简体   繁体   中英

MS Sql-Server timeout

We have this stored procedure below in MS Sql Server. It is run by a job with the same parameters on a daily basis at 5pm. Some days it fails with a timeout error, other times it runs fine. I have tried to reproduce the error, but it is too random.

I know this is ALOT of code to paste in for a question, but I have tried many different things and still can not pinpoint where it could be occurring.

Also, I understand that I am calling some other functions too, but just ignore them for now. If nothing looks wrong with this stored proc, then I will post some of the other functions too.

Please let me know if you need any other info. Thanks.

EDIT: To the commentators below, I don't expect anyone to unravel this code. I am only looking for suggestions as to what could be causing the issue. Thanks to those who have already given me some suggestions.

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

There are two approaches you can take.

1) Increase the timeout.

2) Convert the cursor operations to Set Based SQL Statements. You can probably get significant performance improvements there.

I'm not seeing anything specific- but it's been a while since I've dug into cursors and such things. Two rules of thumb I generally follow (others here have disagreed with me in the past):

1) Cursors are evil. Use them only when you must, for as little as possible.
2) If you find yourself doing a great deal of logic in a SQL Stored Procedure, consider migrating the logic to external code somewhere, so that SQL is doing as little "processing" as possible.

YMMV.

Also, have you put a trace on the procedure (I know it's random, so the likely answer to that is 'no'), and/or have you eliminated resource contention as a possible answer?

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

There is no need that I can see to use cursors for this at all and they should not ever be your first choice in SQL Server anyway.

Likely the times it times out are when there are the most records to process.

I also noticed that you are using a "select...where...in" pointing to a table in another database. In my experience 'in' and 'not in' clauses are as evil as cursors (or even more), unless the table you are pointing to is guaranteed to have only a handful of records.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM