Stored procedure stops running but recompile fixes it [closed] - sql-server

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have a stored procedure that runs a few times a day in SQL Server 2016.
It is nothing more than a few selects that sum a value and count the records. It returns the values as output parameters.
Every so often, maybe once every two months it will just stop working. I will end up getting a time out issue when calling if from code (C#).
Normally it executes in less than one second. If I recompile it, everything returns to normal and I wont have another issue for months.
Any idea what could be causing this?
What additional information can I provide to assist in discovering the issue?
Here is a sample of one of the queries:
SET ANSI_NULLS ON
ALTER PROCEDURE [dbo].[spName]
#dateFrom as datetime,
#dateTo as datetime,
#CustID as varchar(50)
AS
BEGIN
SET NOCOUNT ON;
declare #TotalReturns as decimal(12,0),
#TotalReturnsValue as decimal(12,2),
--Total Transactions and Value for returns within date range
--**********************************************************
select #TotalReturns = count(*), #TotalReturnsValue = sum(cast(isnull([amountField],'0') as decimal(12,2)))
from [tableName]
where [customerField]=#CustID
and [returnDateField] between #dateFrom and #dateTo
and replace([amountField],' ', '') != ''
--**********************************************************
--Outputs
select isnull(#TotalReturns,0) as TotalReturns,
isnull(#TotalReturnsValue,0) as TotalReturnsValue
END

Based on the sample query and the discussion in comments I am pretty sure this is related to parameter sniffing and sub-optimal plans based on data skew across clients and date ranges. You can read about parameter sniffing in depth here. https://www.sqlinthewild.co.za/index.php/2007/11/27/parameter-sniffing/. Gail does a great job explaining the performance challenges with this and a number of ways to combat it.

Related

Are there any advantages in using a single stored procedure for multiple operations or is my teacher wrong? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 months ago.
Improve this question
I'm working on my databases class final project, which consists of making an application that can access and do operations in a database. My teacher insists that I should use a single stored procedure per table:
--In stored procedure "sp_Ciudades"
#Opcion int,
#IdCiudad int = NULL,
#IdEstado int = NULL,
#Nombre varchar(50) = NULL
AS
BEGIN
--Create new record
IF #Opcion = 1
BEGIN
INSERT INTO Ciudades
VALUES(#IdEstado, #Nombre)
END
--Delete record
IF #Opcion = 2
BEGIN
DELETE FROM Ciudades
WHERE IdCiudad = #IdCiudad
END
--Update city
IF #Opcion = 3
BEGIN
UPDATE Ciudades
SET IdEstado = #IdEstado
Nombre = #Nombre
WHERE IdCiudad = #IdCiudad
END
--Retrieve cities
IF #Opcion = 4
BEGIN
SELECT *
FROM Ciudades
WHERE IdCiudad = #IdCiudad OR #IdCiudad = 0 OR #Ciudad IS NULL
END
--Fill cities ComboBox
IF #Opcion = 5
BEGIN
SELECT IdCiudad, Nombre
FROM Ciudades
ORDER BY Nombre
END
END
On the other hand I tried to do something like this:
--In stored procedure "sp_Ciudades_Vista"
#IdCiudad int = NULL
AS
BEGIN
SELECT *
FROM Ciudades
WHERE IdCiudad = #IdCiudad OR #IdCiudad = 0 OR #IdCiudad IS NULL
ORDER BY ID
END
--In stored procedure "sp_Ciudades_Cambio"
#IdCiudad int,
#IdEstado int,
#Nombre varchar(50)
AS
BEGIN
UPDATE Ciudades
SET IdEstado = #IdEstado,
Nombre = #Nombre
WHERE IdCiudad = #IdCiudad
END
I feel the code is much more organized (and encapsulated) and easier to read and understand when defining the command strings in my application (with the numeric options I constantly have to go back to the procedure definition in order to see what each number does). Also, I only use the parameters that are needed to achieve the operation.
However, my teacher says that if I do it this way, the database will have way too many stored procedures since in a real database, there are over 200 options per procedure, and the database may even crash if there's too many procedures in it.
I have already read a similar question and the most voted answer states that:
[...] a separate stored procedure for each operation is best. Otherwise you get too much logic inside your procedures.
But my teacher still insists I should be doing it the other way. Is my teacher's argument true?
What are the advantages of having multiple options/operations inside a single stored procedure?
Are there any advantages? Probably - opening Management Studio could be quicker.
Is your teacher wrong? Yes, most certainly, but as SMor and Jeroen write in the comments: Your teacher does the grading, so he's right until you graduate your class.
Take a look at this question: Generic Stored Procedure for ALL the tables
If you could write a single stored procedure for each table with Create, Read, Update and Delete, then why not build a single generic stored procedure with CRUD operations for ALL the tables? One database - One stored procedure.
Now, apply the logic you would use to determine that this is a bad idea to your problem.
Or apply SOLID principles - they apply to stored procedures as well. You wouldn't write a single method to do 4 wildly different operations based on an input parameter, would you?
Or have a look here: If logic in stored proc.
On first execution SQL Server will explore all the branches, and build a plan - but it will use the parameters seen at that first execution. So assume your first execution is an insert with #IdCiudad = null, then that's what SQL Server will optimize for in the option 4 branch.
Your initial insert will build a select plan (for option 4) where all rows are expected to be returned, meaning a too large memory grant and maybe a parallel plan with hash joins to boot.
Oh, and
WHERE Foo = #foo OR #foo = 0 OR #foo IS NULL
SQL Server won't know how to optimize for this. See Aaron Bertrands article here Kitchen sink design pattern.

SQL Server Stored Procedure Execution timeout - Do I need additional indexes?

I've inherited the following SQL Server stored procedure (on Azure SQL Server):
PROCEDURE [Sources].[DeleteRawCaptures]
(#SourceId BIGINT,
#Count INT OUTPUT)
AS
BEGIN
SET NOCOUNT ON
SET ROWCOUNT 500
DECLARE #BatchId uniqueidentifier
SELECT #BatchId = CaptureBatch
FROM [Data].[RawCaptures]
WHERE CaptureId = (SELECT MAX(CaptureId)
FROM [Data].[RawCaptures]
WHERE SourceId = #SourceId)
DELETE FROM [Data].[RawCaptures]
WHERE SourceId = #SourceId
AND CaptureBatch <> #BatchId
SET #Count = ##ROWCOUNT
END
After many months of this working without issue, it is timing out as of late. The former developer who built the solution, in the brief moment I was able to contact him, suggested it's possible there may be an additional index needed on the Data.RawCaptures table, as the last time he ran into errors many months ago, he needed to add another index. He was not any more specific than that, unfortunately.
I'm not well-versed enough in SQL Server indexes to determine what type of index, and on what columns, I should ensure I have in place, to be certain the above stored procedure is running at it's optimal ability.
These are the indexes that are currently in place:
Just to clarify in case the title of the index does not give enough information:
The first one's fields are CaptureBatch and Status
The second one's field is CaptureDateTime
The third one's fields are SourceId and CaptureBatch
The fourth one's fields are SourceId and Status
The fifth one's field is SourceId
The sixth one's field isStatus
The seventh one's fields are Status and CaptureDateTime
Just FYI, there are two other stored procedures that relate to this process and contain the other fields above that don't appear in the stored procedure that I've posted.
The amount of data in Data.RawCaptures is beginning to increase exponentially. Because of this, I am wondering if I need yet another index for this table (perhaps even of a different type?) or if what I already have should have me well-covered. If the latter is the case, I will start investigating other avenues to determine the cause of the timeouts.
Unfortunately SQL Server Profile is not supported in Azure SQL Database. I'll need to discover another approach.
The Query Execution Plan here:
https://www.brentozar.com/pastetheplan/?id=SJk4pHiw7

StoredProcedure working fast but SSRS working very slow

I am using a stored procedure as a dataset in an SSRS report. Even though the stored procedure is running fast enough, the report is taking too long to process.
For the same set of parameters the stored procedure is giving result in 4-7 seconds but the SSRS report is taking around 4 minutes to pop up.
The data from coming from the stored procedure is big but not too big... its around 13k. Also I cant Implement grouping in Stored Procedure so I am grouping in the report itself. However, even after removing the grouping the performance got better merely (like 40 seconds less time).
Trying to figure out the issue and willing to discuss it as I am having similar issue with 2-3 reports.
Please, any help will be appreciated.
Thank You in advance.
The way a stored procedure is written can affect the performance. from your description if you implement the second procedure below. i believe it will improve the performance.
SLOW Stored Procedure
CREATE PROC SLOW_PROC (#ID INT)
AS
BEGIN
SELECT
ID
,Name
FROM MyTable
WHERE ID =#ID
END
Fast stored procedure
CREATE PROC FAST_PROC (#ID INT)
AS
BEGIN
DECLARE #NewID INT SET #NewID=#ID
SELECT
ID
,Name
FROM MyTable
WHERE ID =#NewID
END
The difference may not be much but the performance is.
I hope this help

Selecting # parameters with SQL [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm doing a couple of tests regarding speed in SQL Server. To do it I have this simple query:
DECLARE #Time1 Date;
DECLARE #Time2 Date;
Set #Time1 = GETDATE();
-- Stuff happening
Set #Time2 = GETDATE();
Now I want to check the values of these properties (Time1 and Time2). I tried doing a SELECT #Time1, Time2 but kept getting errors, so how can I check these values?
EDIT: as I mentioned to the accepted answer author, it was probably some syntax error that was eluding me from using a simple SELECT.
As for the fact the question is On Hold, I really don't see why as it seems a simple question to me. I created #parameters and set a value to them, then I want to check these values.
"Doing a SELECT is not possible" - Who told you this?
DECLARE #Time1 DateTime;
DECLARE #Time2 DateTime;
Set #Time1 = GETDATE();
-- Stuff happening
Set #Time2 = GETDATE();
SELECT
#Time1
,#Time2
I've used this when analysing a large stored procedure, I put some datetime parameters at key points within the stored proc using getdate() and inserted them into an audit table at the end of the procedure. It was really handy for determining which part of the live stored procedure was going slowly for users.
First, perhaps, it is nessecarry to declare the #TimeX as TIME values - not as DATE ....
and than you con use PRINT
Print #Time1
Print #Time2

Error calling stored procedure that have been created in MS SQL Server Management Studio [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 6 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
Let's say I have this procedure :
USE [base1]
GO
SET ANSI_WARNINGS OFF
GO
IF OBJECT_ID ( 'dbo.MyProcedure ', 'P' ) IS NOT NULL DROP PROCEDURE dbo.MyProcedure ;
GO
CREATE PROCEDURE dbo.MyProcedure
#code NVARCHAR(1000),
#Month INT,
#YEAR INT
AS
SET NOCOUNT ON;
-- my code
GO
-- END PROCEDURE
I use the procedure by following steps :
To create it i execute the script of procedure
The procedure is create in this database base1 not in master
I launch this command EXECUTE dbo.MyProcedure N'Test',03,2016; => i get the succesfull result
I disconnect from the server and i reconnect
I execute this : CEXECUTE dbo.MyProcedure N'Test',03,2016; => i get this error
Could not find stored procedure 'dbo.MyProcedure'.
So in custom database base1>Programmability >stored procedures => i can see the procedure it exists
Typically, default database on connection is master. so when you disconnected and reconnected, you most likely are in master database. You can verify by executing SELECT DB_NAME(). Since you created your proc in a different database, execution will fail until you switch databases or fully qualify your proc call.

Resources