June 27, 2005 at 9:08 am
I remember reading DATEDIFF is slow and wherever possible use DATADD.
I have to retrive data for previous month. Is there any elegant way of doing it without using DATEDIFF.
Now I use.
SELECT * FROM MyTable WHERE DATEDIFF(MONTH, MyColumn, GETDATE()) = 1
Regards,
gova
June 27, 2005 at 9:15 am
Don't use functions on a column, check this out :
Select * from dbo.MyTable where DateCol between @StartDate and @EndDate
Just calculte those variables using the dateadd functions (or from the app) and it'll run much faster if the column is indexed.
June 28, 2005 at 8:02 am
...which, for claritys sake, could also look like this
Select *
from dbo.MyTable
where DateCol between DATEADD(MONTH, -1 , GETDATE()) and <A href="mailtoATEDIFF@EndDate">GETDATE())
SQL Server should evaluate your function only once. But check your query plan You don't want it to do it for every row. (Like the DATEDIFF on you column would have to do). And, since we don't have function indexes in SQL Server as in Oracle, it would be a rather unpleasant thing...
//Hans
June 28, 2005 at 9:37 am
"And, since we don't have function indexes in SQL Server as in Oracle, it would be a rather unpleasant thing..."
This isn't 100% accurate :
IF Object_id('Employes2') > 0
DROP TABLE Employes2
GO
IF object_id('fnEmployes2') > 0
DROP FUNCTION fnEmployes2
GO
CREATE FUNCTION [dbo].[fnEmployes2] (@DOB as datetime)
RETURNS SMALLINT
WITH SCHEMABINDING
AS
BEGIN
RETURN CONVERT(SMALLINT, RIGHT(CONVERT(CHAR(8),@DOB,112), 4))
END
GO
CREATE TABLE [Employes2] (
[id] [int] NOT NULL ,
[name] [varchar] (50) ,
[DOB] [datetime] NOT NULL ,
[DOB_MD] AS dbo.fnEmployes2 (DOB)
CONSTRAINT [PK_Employes2] PRIMARY KEY CLUSTERED
(
[id]
) ON [PRIMARY]
) ON [PRIMARY]
CREATE NONCLUSTERED INDEX IX_Employes2_DOB ON dbo.Employes2 (DOB)
GO
INSERT INTO dbo.Employes2 (id, name, dob) Select id, cast(name as varchar(50)), CrDate from dbo.SysObjects
GO
--Select objectproperty(object_id('fnEmployes2'), 'IsDeterministic')
--1
GO
create nonclustered index IX_DayMonth_Of_Birth on dbo.Employes2 (DOB_MD)
GO
Select * from dbo.Employes2 where DOB_MD between 101 and 301
--163 row(s) affected
/*
|--Compute Scalar(DEFINE[Employes2].[DOB_MD]=[dbo].[fnEmployes2](Convert([Employes2].[DOB]))))
|--Bookmark Lookup(BOOKMARK[Bmk1000]), OBJECT[Ideal].[dbo].[Employes2]))
|--Index Seek(OBJECT[Ideal].[dbo].[Employes2].[IX_DayMonth_Of_Birth]), SEEK[Employes2].[DOB_MD] >= Convert([@1]) AND [Employes2].[DOB_MD] > 83% of the query)
*/
GO
Select * from dbo.Employes2 where RIGHT(CONVERT(CHAR(6),DOB,12), 4) between '0101' AND '0301'
--163 row(s) affected
/*
|--Compute Scalar(DEFINE[Employes2].[DOB_MD]=[dbo].[fnEmployes2](Convert([Employes2].[DOB]))))
|--Clustered Index Scan(OBJECT[Ideal].[dbo].[Employes2].[PK_Employes2]), WHEREright(Convert(Convert([Employes2].[DOB])), 4)>='0101' AND right(Convert(Convert([Employes2].[DOB])), 4)<='0301'))
53.75% of the batch
*/
GO
DROP TABLE Employes2
GO
DROP FUNCTION fnEmployes2
GO
This shows how to index a cumputed column based on a function... but I don't know if it can do all the same things that Oracle offers.
June 28, 2005 at 10:08 am
Yeah, I guess you are right. Though it means creating a computed column and using it. One benefit in Oracle is that you can examine the queries executed and to tune them, you just add a function index with the function(s) mostly used...
Here you would have to recode applications or educate users about using the column to gain performance.
But I agree to call the SQL Server solution a function index
June 28, 2005 at 10:17 am
I still have to see a situation where I need to do this. I'm sure it's gonna happen, but maybe not this year . There's almost always a way to write the query where you don't have to do gymnastics like this.
June 28, 2005 at 10:37 am
But the Oracle way of optimizing performance without rewriting the client application can be useful. Though I havn't had any practical use for it yet either
June 28, 2005 at 11:40 am
Good, then I'm still gona go with Sql server .
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply