I am running a stored procedure on SQL Server 2005 and calling it from a VB.net application.
This stored procedure was taking over 3 minutes to run and I started working on way to speed it up. Quite by accident I stumbled on a solution that reduced the run time from 3 minutes to 3 seconds (no joke, I'm dead serious).
But I don't understand why.
The only 2 parameters that I pass are a start date and an end date (used in the WHERE clause) as so:
ALTER PROCEDURE get_OrderLinessByRegion
#DateFrom DATETIME,
#DateTo DATETIME
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
blah, blah, blah
Though some testing I found that when I hard coded the dates in the stored procedure the run times were cut from 3 minutes to 3 seconds.
I ended up with this:
ALTER PROCEDURE get_OrderLinessByRegion
#DateFrom DATETIME,
#DateTo DATETIME
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #StartDate AS DATETIME
DECLARE #EndDate AS DATETIME
SET #StartDate = #DateFrom
SET #EndDate = #DateTo
blah, blah, blah
Can anyone tell me why the second version runs so much faster ?
Thanks so much !!
This sounds like a case of bad parameter sniffing. You can read this article for a detailed explanation. http://sqlinthewild.co.za/index.php/2007/11/27/parameter-sniffing/
Related
We updated our SQL Server database from 2012 to 2016 recently.
Now, our very old C++ programs run into an issue. Very old means, there is no one left who can maintain the code anymore.
The problem is: In the code itself, the Date Fields are initialized as
RFX_Date(pFX, _T("[CREATION_DATE_CENTRAL]"), m_CREATION_DATE_CENTRAL);
The query, which is executed onto the database looks like this:
EXECUTE sp_executesql
N'SELECT * FROM ADDON_Table
WHERE NR = #number
and CREATION_DATE_LOCAL = #date1
and CREATION_DATE_CENTRAL = #date2',
N'#number int, #date1 datetime2, #date2 datetime2',
9817434, '2019-11-19 10:03:22.000', '2019-11-24 19:24:38.5270000';
At least one row should be returned. But the query returns no row.
I figured out, that after changing the datatype of date2 from datetime2 to datetime returns a row.
EXECUTE sp_executesql
N'SELECT * FROM ADDON_Table
WHERE NR = #number
and CREATION_DATE_LOCAL = #date1
and CREATION_DATE_CENTRAL = #date2',
N'#number int, #date1 datetime2, #date2 datetime',
9817434, '2019-11-19 10:03:22.000', '2019-11-24 19:24:38.527';
My conclusion is, that somethings happened after updating the DB to 2016 with the datetime/datetime2 implementation.
Don't know if our Application/ODBC uses from now on datetime2 instead of datetime. Or is there a new behavior of the sp_executesql.
It would be great if someone can help me.
I have implemented a storedprocedure and basically want the storedprocedure to return all records if no parameter is sent or records based on parameter sent. I am using date as the parameter. I am getting an error when executing exec [dbo].[getLog] '27/07/2017' . The error is
Error converting data type varchar to datetime.
Could somebody tell me what is incorrect in the logic
Create PROCEDURE [dbo].[getLog]
#dateFrom datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT * from [CoreAnalytics].[dbo].[Logs]
where [TimeStamp] > ISNULL(#dateFrom, 0) ;
END
GO
If I understand you correct you want to return all records if #dateFrom is null, or filter on that variable.
I think you need something like this then
Create PROCEDURE [dbo].[getLog] #dateFrom datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT * from [CoreAnalytics].[dbo].[Logs]
where (#dateFrom is null or [TimeStamp] > #dateFrom)
END
Make sure you are passing a valid datetime when calling the procedure.
It is best to use an universal format that will work with any database,
yyyyMMdd is a format that will always work.
http://karaszi.com/the-ultimate-guide-to-the-datetime-datatypes
exec [dbo].[getLog] '20170727'
should always work
I have a SQL Server stored procedure that is not returning any data when I plug in my parameter...
ALTER PROCEDURE dbo.EncumBugSearch
#year datetime
AS
BEGIN
SET NOCOUNT ON;
select *
From dbo.BudgetEncumberedTbl as bet
where year(dateadd(month,-3,bet.be_dateposted)) = #year
order by be_dateposted desc
END
GO
This returns nothing, however, when I plug in a number for the parameter (i.e. 2011) then I get the correct results... any ideas?
Your parameter is a datetime, when it should be an int.
When I ran as is, it works perfectly fine but putting this exact code into a stored procedure in SQL 2005 fails.
I get this error
Msg 102, Level 15, State 1, Procedure GetCurrentLoadDate, Line 23.
Incorrect syntax near '#vardate'.
What is wrong with this call that it can work as a declaration and return the result set but fail if put in stored procedures?
declare #date datetime
declare #vardate varchar(10)
set #date = getDate()
set #vardate = CONVERT(varchar(10), #date ,101)
select tableloaded, insertdatetime, sourcesystemdatetime, FriendlyDescription
from dbo.tbl_loadSourcedates_dttm
where CONVERT(varchar(10), insertdatetime, 101) = #vardate
Thanks
Dhiren
You are probably missing the END at the end of the stored proc definition that you neglected to show us. I get the same error If I append
create proc foo
as
begin
to the beginning of your posted code.
Do you have exactly this?
CREATE PROCEDURE GetCurrentLoadDate
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
declare #date datetime
declare #vardate varchar(10)
set #date=getDate()
set #vardate=CONVERT(varchar(10), #date ,101)
select tableloaded,insertdatetime,sourcesystemdatetime,FriendlyDescription
from dbo.tbl_loadSourcedates_dttm
where CONVERT(varchar(10), insertdatetime ,101)=#vardate
END
GO
Because it looks to me that you are missing something when you declare your proc since you are getting a syntax exception on the very first line.
I cannot store the date data type variables using stored procedure. My code is:
ALTER PROCEDURE [dbo].[Access1Register]
-- Add the parameters for the stored procedure here
#MobileNumber int,
#CitizenName varchar(50),
#Dob char(8),
#VerificationCode int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
select CAST(#dob As DATE)
Insert Into Access1 (MobileNo,CitizenName,Dob,VerificationCode)
values(#MobileNumber,#CitizenName,#Dob,#VerificationCode)
go
If I exec this procedure it is executing, but there is an error occured in the date type variable. It's raising the error as invalid item '-'.
It depends on how you pass in the #Dob values.
Your best bet is to use the ISO8601 format - 'YYYYMMDD' - since that will always convert to DATE properly - regardless of your language and regional settings on your SQL Server machine.
It depends on the date format that you pass.
If it is 'mm-dd-yy' you can use CONVERT(DATE, #Dob, 110), if it is 'dd-mm-yy' then CONVERT(DATE, #Dob, 105).
In which format you are passing the #Dob values? And what error you are getting exactly?
If you will pass the #Dob values in the format of mm-dd-yy, it should work correctly and no errors will be there.