我对 SQL Server 2008 R2 上的存储过程有一个非常奇怪的问题。有时,大约每个月一次,我有一个程序变得非常慢,运行大约需要 6 秒而不是几毫秒。但如果我只是简单地重新编译它,而不改变任何东西,它会再次快速运行。它不会发生在所有存储过程上,只有一个(服务器上有几百个)。
我的猜测是当 sp 被编译时,它被缓存并且每次我调用它时都会重用这个缓存,并且这个缓存的版本由于某种原因被破坏了。
我希望也许有些人已经遇到过这种问题,或者至少可以为我指明正确的方向,比如 SQL Server 或 IIS 的哪些配置会影响存储过程缓存?
这是代码:
USE [MyBaseName]
GO
/****** Object: StoredProcedure [dbo].[Publication_getByCriteria] Script Date: 05/29/2013 12:11:07 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Publication_getByCriteria]
@id_sousTheme As int = null,
@id_theme As int = null,
@nbPubli As int = 1000000,
@bActuSite As bit = null,
@bActuPerso As bit = null,
@bActuNewsletter As bit = null,
@bActuChronique As bit = null,
@bActuVideo As bit = null,
@bActuVideoBuzz As bit = null,
@bActuOpportunite As bit = null,
@id_contact As int = null,
@bOnlyPublished As bit = 0,
@bOnlyForHomePage as bit = 0,
@id_contactForTheme As int = null,
@id_newsletter As int = null,
@ID_ActuChronique As int = null,
@sMotClef As varchar(500) = null,
@sMotClefForFullText as varchar(500) = '""',
@dtPublication As datetime = null,
@bParlonsFinance As bit = null,
@bPartenaires as bit = null,
@bUne As bit = null,
@bEditoParlonsFinance As bit = null,
@bEditoQuestionFonds as bit = null,
@dtDebPublication As datetime = null,
@dtFinPublication As datetime = null,
@bOnlyActuWithDroitReponse As bit = 0,
@bActuDroitReponse As bit = null
AS
BEGIN
SET NOCOUNT ON;
DECLARE @dtNow As datetime
SET @dtNow = GETDATE()
SELECT TOP (@nbPubli) p.id_publication, p.sTitre, p.sTexte, p.sTexteHTML, p.dtPublication, p.id_linkedDroitReponse,
si.id_actusite, pe.id_actuPerso, ne.id_actuNewsletter, ac.id_actuChronique, av.id_actuVideo, ap.id_actuOpportunite, ad.id_actuDroitReponse,
c.ID_Contact, c.sPhotoCarre, NULL As sTypePubli, n.id_newsletter,
dbo.Publication_get1Theme(p.id_publication) As theme,
CAST(CASE WHEN ad.id_actuDroitReponse IS NULL THEN 0 ELSE 1 END As bit) As bIsDroitReponse,
coalesce(Personne.sNom, Societe.sNom) as sNom, Personne.sPrenom
FROM Publication p
LEFT OUTER JOIN ActuSite si ON p.id_publication = si.id_publication
LEFT OUTER JOIN ActuPerso pe ON p.id_publication = pe.id_publication
LEFT OUTER JOIN ActuNewsletter ne ON p.id_publication = ne.id_publication
LEFT OUTER JOIN ActuChronique ac ON p.id_publication = ac.id_publication
LEFT OUTER JOIN ActuVideo av ON p.id_publication = av.id_publication
LEFT OUTER JOIN ActuOpportunite ap ON p.id_publication = ap.id_publication
LEFT OUTER JOIN ActuDroitReponse ad ON p.id_publication = ad.id_publication
LEFT OUTER JOIN Contact c ON p.id_contact = c.ID_Contact
LEFT OUTER JOIN Personne ON Personne.id_contact = c.id_contact
LEFT OUTER JOIN Societe ON Societe.id_contact = c.id_contact
LEFT OUTER JOIN Newsletter n ON ne.id_actuNewsletter = n.id_actuNewsletter
WHERE p.bSupp = 0
AND (@bOnlyPublished = 0 Or (@bOnlyPublished = 1 AND p.dtPublication IS NOT NULL AND p.dtPublication < @dtNow))
AND (@id_sousTheme IS NULL Or p.id_publication IN(SELECT id_publication FROM PubliSousTheme WHERE id_soustheme = @id_sousTheme))
AND (@id_theme IS NULL Or p.id_publication IN(SELECT id_publication FROM PubliTheme WHERE id_theme = @id_theme))
AND ((@bActuSite = 1 AND si.id_actusite IS NOT NULL)
OR (@bActuPerso = 1 AND pe.id_actuPerso IS NOT NULL)
OR (@bActuNewsletter = 1 AND ne.id_actuNewsletter IS NOT NULL)
OR (@bActuChronique = 1 AND ac.id_actuChronique IS NOT NULL)
OR (@bActuVideo = 1 AND av.id_actuVideo IS NOT NULL)
OR (@bActuVideoBuzz = 1 AND av.id_actuVideo IS NOT NULL and coalesce(av.sBuzz, '') <> '' )
OR (@bActuOpportunite = 1 AND ap.id_actuOpportunite IS NOT NULL)
OR (@bActuDroitReponse = 1 AND ad.id_actuDroitReponse IS NOT NULL))
AND (@id_contact IS NULL Or p.id_contact = @id_contact)
AND (@id_contactForTheme IS NULL Or
(p.id_publication IN(SELECT id_publication FROM PubliSousTheme
WHERE id_soustheme IN(SELECT id_soustheme FROM ContactSousTheme WHERE id_contact = @id_contactForTheme)))
Or (p.id_publication IN(SELECT id_publication FROM PubliTheme
WHERE id_theme IN(SELECT id_theme FROM ContactTheme WHERE id_contact = @id_contactForTheme)))
)
AND (@ID_ActuChronique is NULL or id_actuChronique = @ID_ActuChronique)
AND (@id_newsletter IS NULL Or p.id_publication IN(SELECT id_publication FROM ListActuNewsletter WHERE id_newsletter = @id_newsletter))
AND (@sMotClef IS NULL
or contains((p.sTexte, p.sTitre), @sMotClefForFullText)
Or Personne.sNom LIKE '%' + @sMotClef + '%' COLLATE Latin1_General_CI_AI
Or Personne.sPrenom LIKE '%' + @sMotClef + '%' COLLATE Latin1_General_CI_AI
Or Societe.sNom LIKE '%' + @sMotClef + '%' COLLATE Latin1_General_CI_AI
)
AND (@dtPublication IS NULL Or p.dtPublication >= @dtPublication)
AND (
@bParlonsFinance IS NULL Or
(@bParlonsFinance = 0 AND p.id_publication NOT IN(SELECT id_publication FROM PubliTheme
WHERE id_theme IN(SELECT id_theme FROM Theme WHERE bParlonsFinance = 1)))
Or (@bParlonsFinance = 1 AND p.id_publication IN(SELECT id_publication FROM PubliTheme
WHERE id_theme IN(SELECT id_theme FROM Theme WHERE bParlonsFinance = 1))))
AND (
@bPartenaires IS NULL Or
(@bPartenaires = 0 AND p.id_publication NOT IN(SELECT id_publication FROM PubliTheme
WHERE id_theme IN(SELECT id_theme FROM Theme WHERE 0 = 1)))
Or (@bPartenaires = 1 AND p.id_publication IN(SELECT id_publication FROM PubliTheme
WHERE id_theme IN(SELECT id_theme FROM Theme WHERE 0 = 1))))
AND (
@bUne IS NULL
Or p.bUne = @bUne)
AND (@bEditoParlonsFinance IS NULL
Or p.bEditoParlonsFinance = @bEditoParlonsFinance)
AND (@bEditoQuestionFonds IS NULL
Or p.bEditoQuestionFonds = @bEditoQuestionFonds)
AND (@dtDebPublication IS NULL Or p.dtPublication >= @dtDebPublication)
AND (@dtFinPublication IS NULL Or p.dtPublication <= @dtFinPublication)
AND (@bOnlyActuWithDroitReponse = 0 Or (@bOnlyActuWithDroitReponse = 1 AND p.id_linkedDroitReponse IS NOT NULL))
and (@bOnlyForHomePage = 0 or (@bOnlyForHomePage = 1 and ac.bHomePage = 1))
ORDER BY coalesce(p.dtPublication, p.dtCreate) DESC, p.id_publication DESC
END