Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 sp_recompile

Author  Topic 

X002548
Not Just a Number

15586 Posts

Posted - 2005-09-22 : 08:49:11
Anyone ever implement this in a sproc?

Pluses or minuses of doing this?

I want to check the length of a transaction in a sproc, log it, and if it exceeds a threshold, I want to do the recompile.

It seems that a very complicated proc (which I did not write) get a plan in the proc cache and it runs in 2 seconds...yeah who thought 2 seconds was ok, but, there are times, especially after a bcp in, that the sproc then takes 22 seconds.

a recompile seems to "fix" it.

Any downside to this method?



Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx

Kristen
Test

22859 Posts

Posted - 2005-09-22 : 09:02:36
"especially after a bcp in"

Aren't the stats shot at that time? Or are you re-creating the Stats after the BCP?

Is the cached SProc query plan no longer suitable for the stats on the table? I thought if the stats for a table/index got rebuilt then that automatically caused any SProc dependent on them to recompile, no?

BoL says this (which I thing is nicely ambiguous!)
quote:

The queries used by stored procedures and triggers are optimized only when they are compiled. As indexes or other changes that affect statistics are made to the database, compiled stored procedures and triggers may lose efficiency. By recompiling stored procedures and triggers that act on a table, you can reoptimize the queries.

Note Microsoft® SQL Server™ automatically recompiles stored procedures and triggers when it is advantageous to do so.


So are you meaning something like this?

CREATE PROCEDURE MySProc
AS
DECLARE @StartTime datetime
SET @StartTime = GetDate()
...
IF DATEDIFF(Second, @StartTime, GetDate()) > 2 EXEC sp_recompile 'MySProc'
RETURN @SomeValue
GO

??

Kristen
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2005-09-22 : 11:19:34
Yup, exactly....

I like the part...

ote Microsoft® SQL Server™ automatically recompiles stored procedures and triggers when it is advantageous to do so.

Which is when?



Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx
Go to Top of Page

SamC
White Water Yakist

3467 Posts

Posted - 2005-09-22 : 11:51:39
I recompile every night to avoid nits... I've got a proc someone (Tara maybe) at SQLTeamp posted which'll tag all procs for recompile.
Go to Top of Page

jen
Master Smack Fu Yak Hacker

4110 Posts

Posted - 2005-09-23 : 04:42:22
i do recompiles every week, scheduled and it has improve query performance compare to before

no downside so far

--------------------
keeping it simple...
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2005-09-23 : 04:57:34
From BOL
quote:
As a database is changed by such actions as adding indexes or changing data in indexed columns, the original query plans used to access its tables should be optimized again by recompiling them. This optimization happens automatically the first time a stored procedure is run after Microsoft® SQL Server™ 2000 is restarted. It also occurs if an underlying table used by the stored procedure changes. But if a new index is added from which the stored procedure might benefit, optimization does not automatically happen (until the next time the stored procedure is run after SQL Server is restarted).


I'm interested to know this
Is it necessary to Recompile even if there is no change in the Table definitions?

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

jen
Master Smack Fu Yak Hacker

4110 Posts

Posted - 2005-09-23 : 05:13:21
quote:
Originally posted by madhivanan

From BOL
quote:
As a database is changed by such actions as adding indexes or changing data in indexed columns, the original query plans used to access its tables should be optimized again by recompiling them. This optimization happens automatically the first time a stored procedure is run after Microsoft® SQL Server™ 2000 is restarted. It also occurs if an underlying table used by the stored procedure changes. But if a new index is added from which the stored procedure might benefit, optimization does not automatically happen (until the next time the stored procedure is run after SQL Server is restarted).


I'm interested to know this
Is it necessary to Recompile even if there is no change in the Table definitions?

Madhivanan

Failing to plan is Planning to fail



--------------------
keeping it simple...
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2005-09-23 : 07:39:58
"i do recompiles every week, scheduled and it has improve query performance compare to before"

Interesting. Rebooting the server would work too!!!

I'm slightly more inclined to recompiling a few each night (Monday = A-D, Tuesday = E-G ...) so that the server does not take a hit of ALL of them going at once - is that daft?

I was glibly assuming that diligently REINDEXING, DEFRAGGING and UPDATING STATS was getting me to the finishing line

Kristen
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2005-09-23 : 12:05:33
Well it happened again, they did another ledger load and the sproc went itno the crapper....

Did a trace this time, and see the length of the trans as 22 seconds, so it is the plan.

Did a recompile and was immediatley back to 2 seconds


So.....I wanted to modify the sproc to check the length of the nested sproc from the calling sproc, and if it exceeds5 seconds or whatever, to do the recompile.

Only thing is, we only grant the connection pooling id execute on the sprocs, so the test I ran failed with permissions.

Any thoughts?



Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2005-09-23 : 14:34:43
"Any thoughts?"

Insert the name of the SProc-to-be-recompiled into a please-recompile-me table, and have a scheduled job come along, with sufficient permissions , and do the actual recompile.

Perhaps the "ledger load" job could be responsible for doing the recompile (or adding its name to the please-recompile-me table)

Kristen
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2005-09-23 : 14:45:34
I wanted to do logging anyway


USE Northwind
GO

CREATE TABLE myLog99(
Sproc varchar(255)
, Log_dt datetime DEFAULT (GetDate())
, spid int
, Duration int
, [SYSTEM_USER] varchar(30))
GO

CREATE PROC mySproc99
AS
SET NOCOUNT ON
DECLARE @s datetime, @x int, @y int
SELECT @s = GetDate()
SELECT @x = RIGHT(CONVERT(varchar(25),GETDATE(),121),3)*996, @y = 1
WHILE @y < @x
SELECT @y = @y + 1
SELECT COUNT(*) FROM Orders
INSERT INTO myLog99(Sproc, spid, Duration, [SYSTEM_USER])
SELECT 'mySproc99', @@SPID, DATEDIFF(ms,@s,GetDate()),SYSTEM_USER
SET NOCOUNT OFF
GO

CREATE PROC myDriver99
AS
SET NOCOUNT ON
IF (SELECT DISTINCT Duration
FROM myLog99
WHERE Duration = (SELECT MAX(Duration) FROM myLog99)) < 1000
BEGIN
PRINT 'WITH RECOMPILE'
EXEC mySproc99 WITH RECOMPILE
END
ELSE
BEGIN
PRINT 'NO RECOMPILE'
EXEC mySproc99
END
SET NOCOUNT OFF
GO

EXEC myDriver99
GO
EXEC myDriver99
GO
EXEC myDriver99
GO
EXEC myDriver99
GO

SELECT * FROM myLog99 order by Log_dt DESC
GO

DROP TABLE myLog99
DROP PROC myDriver99, mySproc99
GO





Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2005-09-24 : 00:24:04
As a matter of interest why do you want to store the @@SPID? Is it useful after-the-fact?

We have an SProc do the Insert Into Log - keeps it out of the execution plan of the mySproc99, and allows us to change it en masse if needs be - e.g. the first time you get a user with SYSTEM_USER more than 30 characters!

However, I have no idea how much more "expensive" that is compared to just doing an INSERT within the SProc itself. Any thoughts?

Do you need myDriver99 to check for "slow running" only since the last time it ran? Otherwise once you get a high value in the log that will cause the MAX(duration) to force recompile every time.

Is there a risk with this strategy that one task that slows the whole server will cause the whole world to re-compile (e.g. the reindex job)? Maybe the average runtime over the last n minutes (or since the last time it was checked), or the average of upper-quartile durations, would be a better threshold?

SELECT AVG(Duration)
FROM
(
SELECT TOP 100 Duration
FROM myLog99
ORDER BY Log_dt DESC
) X

You might want to have myDriver99 purge stale entries from the log - to save having to have a separate housekeeping cleardown (depends on whether the cleardown would be better done during slack time I suppose)

Actually, here's a bit of a thought, probably rubbish!

From mySproc99 call a "LogMe" SProc. That inserts the time/user/duration and name into the LOG. Then it checks what max runtime is permitting (in a lookup table by SProc name), and if that is exceeded recompiles it. (Perhaps if the current duration > threshold it calculates the average duration of the last 100 executions, or whatever, rather than just using the current duration - to avoid getting recompiles because of a single long run during index rebuild etc.)

The "threshold" in the lookup table could be freshened daily based on actual running times - so if, over time, mySproc99 average duration slips from 100ms to 150ms (database gets bigger, whatever) then the threshold for recompile could slip with it.

Kristen
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2005-09-26 : 10:19:35
Thanks Kristen, But what I'm seeing is that once it goes to 22 seconds, it stays that way, until the prod dba does a recompile. She did tell me she recompiled everything, which I wish she hadn't.

I did a trace though, and saw the sproc itself have a duration of 22 seconds, so it is a bad plan, and the load is causing it.

Could you explain this though?

quote:

Is there a risk with this strategy that one task that slows the whole server will cause the whole world to re-compile (e.g. the reindex job)? Maybe the average runtime over the last n minutes (or since the last time it was checked), or the average of upper-quartile durations, would be a better threshold?





Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2005-09-26 : 14:26:20
"Could you explain this though?"

Looked like your "specification" was going to do:

What's the MAX execution duration of the SProc? If greater than 21.999999 seconds recompile it!

Clearly your [specific] SProc is either running at 2 seconds or 20 seconds, so there is a wide gulf in the middle. However, if you were building something generic it would be a pity to rebuild an SProc that ran all the time at 2 seconds, but took 3 seconds when the server was otherwise busy - e.g. if an Index Rebuild was in progress. Therefore I thought that having an average of recent durations would be better than a Spot time. That might be coupled, now I think about it, with a recompile after a REALLY bad duration time - so, 2 seconds is OK. 10 seconds is OK provided the average over the last 10 minutes is less than 15 seconds. However, a single execution with a duration > 20 seconds needs a recompile.

Even that worries me - maybe calculating the query plan will take 19.5 seconds - so a recompile will cause a run time of > 20 seconds, and thus an immediate recompile. So I think an Average of at least N runs, is always preferable to recompile after a single bad spot-time.

Kristen
Go to Top of Page
   

- Advertisement -