Stored Procedure is taking longer than raw SQL

Hey Experts,

I am seeking help for a very strange issue I am having with a stored procedure and it's execution time.

I have a store procedure that when run on its own (as a set of queries) runs in about 3-5 minutes.  However, when I execute it as a stored procedure it takes over 30 minutes to run.  This stored procedure is pretty long and hits several views and tables, but no other stored procedures.

Here is the weird part, if I declare new variable that are the same as the ones being passed to the procedure, then assign the new variables to the values of the parameters being passed, it runs in 3-5 minutes again.  I know this last bit is a little confusing, so below is an example.

This is a SQL server running MS SQL 2005.  Also, I have already tried recompiling the stored procedure, and that hasn't helped the problem.  

Example:

Raw Queries (takes 3-5 minutes to run)
DECLARE @VariableA VARCHAR(50)
DECLARE @VariableB VARCHAR(50)
DECLARE @VariableC VARCHAR(50)

SET @VariableA = 'ABC'
SET @VariableB = 'DEF'
SET @VariableC = 'GHI'

SELECT * FROM [FirstSelect] WHERE ColumnA = @VariableA
SELECT * FROM [SecondSelect] WHERE ColumnB = @VariableB
SELECT * FROM [LastSelect] WHERE ColumnC = @VariableC

Open in new window

As Stored Procedure (Takes 30+ minutes to run as a stored procedure)
CREATE PROCEDURE myStoredProcedure
	@VariableA VARCHAR(50) = '0',    
	@VariableB VARCHAR(50) = '0',    
	@VariableC VARCHAR(50) = '0'
AS
	SELECT * FROM [FirstSelect] WHERE ColumnA = @VariableA
	SELECT * FROM [SecondSelect] WHERE ColumnB = @VariableB
	SELECT * FROM [LastSelect] WHERE ColumnC = @VariableC
GO

EXEC myStoredProcedure 
	@VariableA = 'ABC', 
	@VariableB = 'DEF', 
	@VariableC = 'GHI'

Open in new window

Very strange way that makes the stored procedure run faster (3-6 minutes)
CREATE PROCEDURE myStoredProcedure
	@VariableA VARCHAR(50) = '0',    
	@VariableB VARCHAR(50) = '0',    
	@VariableC VARCHAR(50) = '0'
AS
	DECLARE @VariableA1 VARCHAR(50)
	DECLARE @VariableB1 VARCHAR(50)
	DECLARE @VariableC1 VARCHAR(50)

	SET @VariableA1 = @VariableA
	SET @VariableB1 = @VariableB
	SET @VariableC1 = @VariableC

	SELECT * FROM [FirstSelect] WHERE ColumnA = @VariableA1
	SELECT * FROM [SecondSelect] WHERE ColumnB = @VariableB1
	SELECT * FROM [LastSelect] WHERE ColumnC = @VariableC1
GO
EXEC myStoredProcedure 
	@VariableA = 'ABC', 
	@VariableB = 'DEF', 
	@VariableC = 'GHI'
GO

Open in new window

LVL 1
StarbucksDrinkerAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jogosCommented:
Run both versions and compare execution plans.

Then UPDATE STATISTICS and do the same.
0
Éric MoreauSenior .Net ConsultantCommented:
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
StarbucksDrinkerAuthor Commented:
Isn't UPDATE STATISTICS for tables and indexed views?  Would that need to be run on every table and indexed view that we are hitting in the stored procedure?
0
IT Pros Agree: AI and Machine Learning Key

We’d all like to think our company’s data is well protected, but when you ask IT professionals they admit the data probably is not as safe as it could be.

Scott PletcherSenior DBACommented:
I would try recompiling the procedure every time to avoid using a poorly matching plan from a previous run.


CREATE PROCEDURE myStoredProcedure
      @VariableA VARCHAR(50) = '0',    
      @VariableB VARCHAR(50) = '0',    
      @VariableC VARCHAR(50) = '0'
WITH RECOMPILE
AS
...
0
Éric MoreauSenior .Net ConsultantCommented:
just prevent parameter sniffing by using variables as in your last example
0
Scott PletcherSenior DBACommented:
Local variables will often give you a poor plan as well.  They force SQL to use generic estimates for the plan instead of the actual values being passed in.

Recompiling is typically the best option.  If the proc is running 3+ minutes, the recompile time will not be significant.

Thus, as a general rule, you should always try RECOMPILE first.

In certain specific cases, local variables may perform better than recompiling, but that can be detected later.
0
StarbucksDrinkerAuthor Commented:
Awesome, this totally explains the problem!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft SQL Server 2005

From novice to tech pro — start learning today.