2011-05-02 4 views
1

Nous avons cette procédure stockée ci-dessous dans MS SQL Server. Il est géré par un travail avec les mêmes paramètres tous les jours à 17h. Certains jours, il échoue avec une erreur de délai, d'autres fois il fonctionne bien. J'ai essayé de reproduire l'erreur, mais c'est trop aléatoire.MS Sql-Server timeout

Je sais que c'est beaucoup de code à coller pour une question, mais j'ai essayé beaucoup de choses différentes et je n'arrive toujours pas à savoir où cela pourrait se produire.

Aussi, je comprends que j'appelle d'autres fonctions aussi, mais juste les ignorer pour l'instant. Si rien ne semble pas correct avec ce proc stocké, alors je posterai aussi certaines des autres fonctions.

S'il vous plaît laissez-moi savoir si vous avez besoin d'autres informations. Merci.

EDIT: Pour les commentateurs ci-dessous, je ne m'attends pas à ce que quiconque découvre ce code. Je ne cherche que des suggestions sur ce qui pourrait causer le problème. Merci à ceux qui m'ont déjà fait des 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 [email protected]) 
      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 [email protected] 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 
+0

voir ces curseurs? vous allez donc à la base de données enfer! –

+0

maintenez-vous vos statistiques et vos index à jour? –

+0

tl; dr Désolés, vous attendez de nous que nous décrivions ce code? Et ce n'est pas le * code réel réel * non plus donc toute suggestion que nous offrons serait pour le * code * échantillon que vous avez posté – gbn

Répondre

1

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

Il n'y a pas besoin que je peux voir utiliser des curseurs pour du tout et ils ne devraient jamais être votre premier choix dans SQL Server de toute façon.

Il est probable que les heures d'expiration sont celles où il y a le plus d'enregistrements à traiter.

+0

L'une des réponses ci-dessous aurait aidé. Merci à tous!J'ai choisi ceci comme réponse acceptée parce que le lien m'a aidé le plus. –

1

Il existe deux approches possibles.

1) Augmentez le délai.

2) Convertissez les opérations de curseur en instructions SQL définies. Vous pouvez probablement obtenir des améliorations significatives de performance là-bas.

1

Je ne vois rien de spécifique - mais cela fait un moment que j'ai creusé dans des curseurs et de telles choses. Deux règles de base que je suis généralement (d'autres ici ont été en désaccord avec moi dans le passé):

1) Les curseurs sont mauvais. Utilisez-les seulement quand vous le devez, pour le moins possible.
2) Si vous trouvez que vous faites beaucoup de logique dans une procédure stockée SQL, envisagez de migrer la logique vers un code externe quelque part, afin que SQL fasse le moins de "traitement" possible.

YMMV.

De même, avez-vous mis une trace sur la procédure (je sais que c'est aléatoire, donc la réponse probable est 'non'), et/ou avez-vous éliminé la contention des ressources comme réponse possible?

0

J'ai également remarqué que vous utilisez un "select ... where ... in" pointant vers une table dans une autre base de données. D'après mon expérience, les clauses 'in' et 'not in' sont aussi mauvaises que les curseurs (ou même plus), à moins que la table que vous pointez soit sûre d'avoir seulement une poignée d'enregistrements.

Questions connexes