Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 116961
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T03:15:38+00:00 2026-05-11T03:15:38+00:00

A query runs fast: DECLARE @SessionGUID uniqueidentifier SET @SessionGUID = ‘BCBA333C-B6A1-4155-9833-C495F22EA908’ SELECT * FROM

  • 0

A query runs fast:

DECLARE @SessionGUID uniqueidentifier SET @SessionGUID = 'BCBA333C-B6A1-4155-9833-C495F22EA908'  SELECT * FROM Report_Opener WHERE SessionGUID = @SessionGUID ORDER BY CurrencyTypeOrder, Rank 

subtree cost: 0.502

But putting the same SQL in a stored procedure runs slow, and with a totally different execution plan

CREATE PROCEDURE dbo.ViewOpener @SessionGUID uniqueidentifier AS SELECT * FROM Report_Opener WHERE SessionGUID = @SessionGUID ORDER BY CurrencyTypeOrder, Rank  EXECUTE ViewOpener @SessionGUID 

Subtree cost: 19.2

I’ve run

sp_recompile ViewOpener 

And it still runs the same (badly), and I’ve also changed the stored procedure to

CREATE PROCEDURE dbo.ViewOpener @SessionGUID uniqueidentifier AS SELECT *, 'recompile please' FROM Report_Opener WHERE SessionGUID = @SessionGUID ORDER BY CurrencyTypeOrder, Rank 

And back again, trying to really trick it into recompiling.

I’ve dropped and recreated the stored procedure in order to get it to generate a new plan.

I’ve tried forcing recompiles, and prevent parameter sniffing, by using a decoy variable:

CREATE PROCEDURE dbo.ViewOpener @SessionGUID uniqueidentifier AS  DECLARE @SessionGUIDbitch uniqueidentifier SET @SessionGUIDbitch = @SessionGUID  SELECT * FROM Report_Opener WHERE SessionGUID = @SessionGUIDbitch ORDER BY CurrencyTypeOrder, Rank 

I’ve also tried defining the stored procedure WITH RECOMPILE:

CREATE PROCEDURE dbo.ViewOpener @SessionGUID uniqueidentifier  WITH RECOMPILE AS SELECT * FROM Report_Opener WHERE SessionGUID = @SessionGUID ORDER BY CurrencyTypeOrder, Rank 

So that it’s plan is never cached, and I’ve tried forcing a recompile at execute:

EXECUTE ViewOpener @SessionGUID WITH RECOMPILE 

Which didn’t help.

I’ve tried converting the procedure to dynamic SQL:

CREATE PROCEDURE dbo.ViewOpener @SessionGUID uniqueidentifier  WITH RECOMPILE AS DECLARE @SQLString NVARCHAR(500)  SET @SQLString = N'SELECT *    FROM Report_OpenerTest    WHERE SessionGUID = @SessionGUID    ORDER BY CurrencyTypeOrder, Rank'  EXECUTE sp_executesql @SQLString, N'@SessionGUID uniqueidentifier', @SessionGUID 

Which didn’t help.

The entity ‘Report_Opener‘ is a view, which is not indexed. The view only references underlying tables. No table contains computed columns, indexed or otherwise.

For the hell of it I tried creating the view with

SET ANSI_NULLS ON SET QUOTED_IDENTIFER ON 

That didn’t fix it.

How is it that

  • the query is fast
  • moving the query to a view, and selecting from the view is fast
  • selecting from the view from a stored procedure is 40x slower?

I tried moving the definition of the view directly into the stored procedure (violating 3 business rules, and breaking an important encapsulation), and that makes it only about 6x slower.

Why is the stored procedure version so slow? What can possibly account for SQL Server running ad-hoc SQL faster than a different kind of ad-hoc SQL?

I’d really rather not

  • embed the SQL in code
  • change the code at all

    Microsoft SQL Server  2000 - 8.00.2050 (Intel X86) Mar  7 2008 21:29:56 Copyright (c) 1988-2003 Microsoft Corporation Standard Edition on Windows NT 5.2 (Build 3790: Service Pack 2) 

But what can account for SQL Server being unable to run as fast as SQL Sever running a query, if not parameter sniffing.


My next attempt will be to have StoredProcedureA call StoredProcedureB call StoredProcedureC call StoredProcedureD to query the view.

And failing that, have the stored procedure call a stored procedure, call a UDF, call a UDF, call a stored procedure, call a UDF to query the view.


To sum up, the following run fast from QA, but slow when put into a stored procedure:

The original:

--Runs fine outside of a stored procedure SELECT * FROM Report_OpenerTest WHERE SessionGUID = @SessionGUID ORDER BY CurrencyTypeOrder, Rank 

sp_executesql:

--Runs fine outside of a stored procedure DECLARE @SQLString NVARCHAR(500) SET @SQLString = N'SELECT * FROM Report_OpenerTest WHERE SessionGUID = @SessionGUID ORDER BY CurrencyTypeOrder, Rank'  EXECUTE sp_executesql @SQLString,         N'@SessionGUID uniqueidentifier',         @SessionGUID 

EXEC(@sql):

--Runs fine outside of a stored procedure DECLARE @sql NVARCHAR(500) SET @sql = N'SELECT * FROM Report_OpenerTest WHERE SessionGUID = '''+CAST(@SessionGUID AS varchar(50))+''' ORDER BY CurrencyTypeOrder, Rank'  EXEC(@sql) 

Execution Plans

The good plan:

      |--Sort(ORDER BY:([Expr1020] ASC, [Currencies].[Rank] ASC))            |--Compute Scalar(DEFINE:([Expr1020]=If ([Currencies].[CurrencyType]='ctCanadianCash') then 1 else If ([Currencies].[CurrencyType]='ctMiscellaneous') then 2 else If ([Currencies].[CurrencyType]='ctTokens') then 3 else If ([Currencies].[CurrencyType]                 |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Openers].[OpenerGUID]))                      |--Filter(WHERE:((([Currencies].[IsActive]<>0 AND [Currencies].[OnOpener]<>0) AND ((((((([Currencies].[CurrencyType]='ctUSCoin' OR [Currencies].[CurrencyType]='ctMiscellaneousUS') OR [Currencies].[CurrencyType]='ctUSCash') OR [Currencies].                      |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Currencies].[CurrencyGUID], [Openers].[OpenerGUID]) WITH PREFETCH)                      |         |--Nested Loops(Left Outer Join)                      |         |    |--Bookmark Lookup(BOOKMARK:([Bmk1016]), OBJECT:([GrobManagementSystemLive].[dbo].[Windows]))                      |         |    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([Openers].[WindowGUID]))                      |         |    |         |--Bookmark Lookup(BOOKMARK:([Bmk1014]), OBJECT:([GrobManagementSystemLive].[dbo].[Openers]))                      |         |    |         |    |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Openers].[IX_Openers_SessionGUID]), SEEK:([Openers].[SessionGUID]=[@SessionGUID]) ORDERED FORWARD)                      |         |    |         |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Windows].[IX_Windows]), SEEK:([Windows].[WindowGUID]=[Openers].[WindowGUID]) ORDERED FORWARD)                      |         |    |--Clustered Index Scan(OBJECT:([GrobManagementSystemLive].[dbo].[Currencies].[IX_Currencies_CurrencyType]))                      |         |--Clustered Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[OpenerDetails].[IX_OpenerDetails_OpenerGUIDCurrencyGUID]), SEEK:([OpenerDetails].[OpenerGUID]=[Openers].[OpenerGUID] AND [OpenerDetails].[CurrencyGUID]=[Currenc                      |--Hash Match(Cache, HASH:([Openers].[OpenerGUID]), RESIDUAL:([Openers].[OpenerGUID]=[Openers].[OpenerGUID]))                           |--Stream Aggregate(DEFINE:([Expr1006]=SUM(If (((([Currencies].[CurrencyType]='ctMiscellaneous' OR [Currencies].[CurrencyType]='ctTokens') OR [Currencies].[CurrencyType]='ctChips') OR [Currencies].[CurrencyType]='ctCanadianCoin') OR [                                |--Nested Loops(Inner Join, OUTER REFERENCES:([OpenerDetails].[CurrencyGUID]) WITH PREFETCH)                                     |--Nested Loops(Inner Join)                                     |    |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Openers].[IX_Openers_OneOpenerPerSession]), SEEK:([Openers].[OpenerGUID]=[Openers].[OpenerGUID]) ORDERED FORWARD)                                     |    |--Clustered Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[OpenerDetails].[IX_OpenerDetails_OpenerGUIDCurrencyGUID]), SEEK:([OpenerDetails].[OpenerGUID]=[Openers].[OpenerGUID]) ORDERED FORWARD)                                     |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Currencies].[PK_Currencies_CurrencyGUID]), SEEK:([Currencies].[CurrencyGUID]=[OpenerDetails].[CurrencyGUID]) ORDERED FORWARD) 

The bad plan

       |--Sort(ORDER BY:([Expr1020] ASC, [Currencies].[Rank] ASC))             |--Compute Scalar(DEFINE:([Expr1020]=If ([Currencies].[CurrencyType]='ctCanadianCash') then 1 else If ([Currencies].[CurrencyType]='ctMiscellaneous') then 2 else If ([Currencies].[CurrencyType]='ctTokens') then 3 else If ([Currencies].[Currency                  |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Openers].[OpenerGUID]))                       |--Filter(WHERE:((([Currencies].[IsActive]<>0 AND [Currencies].[OnOpener]<>0) AND ((((((([Currencies].[CurrencyType]='ctUSCoin' OR [Currencies].[CurrencyType]='ctMiscellaneousUS') OR [Currencies].[CurrencyType]='ctUSCash') OR [Currenc                       |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Currencies].[CurrencyGUID], [Openers].[OpenerGUID]) WITH PREFETCH)                       |         |--Filter(WHERE:([Openers].[SessionGUID]=[@SessionGUID]))                       |         |    |--Concatenation                       |         |         |--Nested Loops(Left Outer Join)                       |         |         |    |--Table Spool                       |         |         |    |    |--Hash Match(Inner Join, HASH:([Windows].[WindowGUID])=([Openers].[WindowGUID]), RESIDUAL:([Windows].[WindowGUID]=[Openers].[WindowGUID]))                       |         |         |    |         |--Clustered Index Scan(OBJECT:([GrobManagementSystemLive].[dbo].[Windows].[IX_Windows_CageGUID]))                       |         |         |    |         |--Table Scan(OBJECT:([GrobManagementSystemLive].[dbo].[Openers]))                       |         |         |    |--Table Spool                       |         |         |         |--Clustered Index Scan(OBJECT:([GrobManagementSystemLive].[dbo].[Currencies].[IX_Currencies_CurrencyType]))                       |         |         |--Compute Scalar(DEFINE:([Openers].[OpenerGUID]=NULL, [Openers].[SessionGUID]=NULL, [Windows].[UseChipDenominations]=NULL))                       |         |              |--Nested Loops(Left Anti Semi Join)                       |         |                   |--Clustered Index Scan(OBJECT:([GrobManagementSystemLive].[dbo].[Currencies].[IX_Currencies_CurrencyType]))                       |         |                   |--Row Count Spool                       |         |                        |--Table Spool                       |         |--Clustered Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[OpenerDetails].[IX_OpenerDetails_OpenerGUIDCurrencyGUID]), SEEK:([OpenerDetails].[OpenerGUID]=[Openers].[OpenerGUID] AND [OpenerDetails].[CurrencyGUID]=[Cu                       |--Hash Match(Cache, HASH:([Openers].[OpenerGUID]), RESIDUAL:([Openers].[OpenerGUID]=[Openers].[OpenerGUID]))                            |--Stream Aggregate(DEFINE:([Expr1006]=SUM([partialagg1034]), [Expr1007]=SUM([partialagg1035]), [Expr1008]=SUM([partialagg1036]), [Expr1009]=SUM([partialagg1037]), [Expr1010]=SUM([partialagg1038]), [Expr1011]=SUM([partialagg1039]                                 |--Nested Loops(Inner Join)                                      |--Stream Aggregate(DEFINE:([partialagg1034]=SUM(If (((([Currencies].[CurrencyType]='ctMiscellaneous' OR [Currencies].[CurrencyType]='ctTokens') OR [Currencies].[CurrencyType]='ctChips') OR [Currencies].[CurrencyType]='                                      |    |--Nested Loops(Inner Join, OUTER REFERENCES:([OpenerDetails].[CurrencyGUID]) WITH PREFETCH)                                      |         |--Clustered Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[OpenerDetails].[IX_OpenerDetails_OpenerGUIDCurrencyGUID]), SEEK:([OpenerDetails].[OpenerGUID]=[Openers].[OpenerGUID]) ORDERED FORWARD)                                      |         |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Currencies].[PK_Currencies_CurrencyGUID]), SEEK:([Currencies].[CurrencyGUID]=[OpenerDetails].[CurrencyGUID]) ORDERED FORWARD)                                      |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Openers].[IX_Openers_OneOpenerPerSession]), SEEK:([Openers].[OpenerGUID]=[Openers].[OpenerGUID]) ORDERED FORWARD) 

The bad-one is eager spooling 6 million rows; the other one isn’t.

Note: This isn’t a question about tuning a query. I have a query that runs lightning fast. I just want SQL Server to run fast from a stored procedure.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-11T03:15:39+00:00Added an answer on May 11, 2026 at 3:15 am

    I found the problem, here’s the script of the slow and fast versions of the stored procedure:

    dbo.ViewOpener__RenamedForCruachan__Slow.PRC

    SET QUOTED_IDENTIFIER OFF  GO SET ANSI_NULLS OFF  GO  CREATE PROCEDURE dbo.ViewOpener_RenamedForCruachan_Slow     @SessionGUID uniqueidentifier AS  SELECT * FROM Report_Opener_RenamedForCruachan WHERE SessionGUID = @SessionGUID ORDER BY CurrencyTypeOrder, Rank GO  SET QUOTED_IDENTIFIER OFF  GO SET ANSI_NULLS ON  GO 

    dbo.ViewOpener__RenamedForCruachan__Fast.PRC

    SET QUOTED_IDENTIFIER OFF  GO SET ANSI_NULLS ON  GO  CREATE PROCEDURE dbo.ViewOpener_RenamedForCruachan_Fast     @SessionGUID uniqueidentifier  AS  SELECT * FROM Report_Opener_RenamedForCruachan WHERE SessionGUID = @SessionGUID ORDER BY CurrencyTypeOrder, Rank GO  SET QUOTED_IDENTIFIER OFF  GO SET ANSI_NULLS ON  GO 

    If you didn’t spot the difference, I don’t blame you. The difference is not in the stored procedure at all. The difference that turns a fast 0.5 cost query into one that does an eager spool of 6 million rows:

    Slow: SET ANSI_NULLS OFF

    Fast: SET ANSI_NULLS ON


    This answer also could be made to make sense, since the view does have a join clause that says:

    (table.column IS NOT NULL) 

    So there is some NULLs involved.


    The explanation is further proved by returning to Query Analizer, and running

    SET ANSI_NULLS OFF 

    .

    DECLARE @SessionGUID uniqueidentifier SET @SessionGUID = 'BCBA333C-B6A1-4155-9833-C495F22EA908' 

    .

    SELECT * FROM Report_Opener_RenamedForCruachan WHERE SessionGUID = @SessionGUID ORDER BY CurrencyTypeOrder, Rank 

    And the query is slow.


    So the problem isn’t because the query is being run from a stored procedure. The problem is that Enterprise Manager’s connection default option is ANSI_NULLS off, rather than ANSI_NULLS on, which is QA’s default.

    Microsoft acknowledges this fact in KB296769 archive

    BUG: Cannot use SQL Enterprise Manager to create stored procedures containing linked server objects

    Cause

    By default, SQL Server 2000 Enterprise Manager sets ANSI_NULLS to OFF before creating a stored procedure.

    The given workaround is to include the ANSI_NULLS option in the stored procedure dialog:

    Set ANSI_NULLS ON Go Create Proc spXXXX as .... 
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 274k
  • Answers 274k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer StyleCop enforces some things here: Within a class, struct, or… May 13, 2026 at 2:25 pm
  • Editorial Team
    Editorial Team added an answer Fixed it by making sure the Realm setting "Assign Groups"… May 13, 2026 at 2:25 pm
  • Editorial Team
    Editorial Team added an answer The problem with the first version is that if you… May 13, 2026 at 2:25 pm

Related Questions

A query runs fast: DECLARE @SessionGUID uniqueidentifier SET @SessionGUID = 'BCBA333C-B6A1-4155-9833-C495F22EA908' SELECT * FROM
I have a sql query that runs super fast, around one second, when not
I have this query in SQL Server 2005: SELECT J.JobID, dbo.tblCustomers.Name AS CustomerName, J.CustomerJobNumber,
I have a query in my application that runs very fast when there are
I have a query that runs super fast when executed in the sql editor

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.