I have a table with the following structure:
CREATE TABLE MyTable (
ID int identity,
Whatever varchar(100),
MyTime time(2) NOT NULL,
MyDate date NOT NULL,
MyDateTime AS (DATEADD(DAY, DATEDIFF(DAY, '19000101', [MyDate]),
CAST([MyDate] AS DATETIME2(2))))
)
The computed column adds date and time into a single datetime2 field.
Most queries against the table have one or more of the following clauses:
... WHERE MyDate < @filter1 and MyDate > @filter2
... ORDER BY MyDate, MyTime
... ORDER BY MyDateTime
In a nutshell, date is usually used for filtering, and full datetime is used for sorting.
Now for questions:
-
What is the best way to set indices on those 3 date-time columns? 2 separate on
dateandtimeor maybe 1 ondateand 1 on compositedatetime, or something else? Quite a lot of inserts and updates occur on this table, and I’d like to avoid over-indexing. -
As I wrote this question, I noticed the long and kind of ugly computed column definition. I picked it up from somewhere a while ago and forgot to investigate if there’s a simpler way of doing it. Is there any easier way of combining a
dateandtime2into adatetime2? Simple addition does not work, and I’m not sure if I should avoid casting tovarchar, combining and casting back.
Having date and time in two separate columns may seem peculiar but if you have queries that use only the date (and/or especially only the time part), I think it’s a valid decision. You can create an index on date only or on time or on (date, whatever), etc.
What I don’t understand is why you also have the computed datetime column as well. There s no reason to store this value, too. It can easily be calculated when needed.
And if you need to order by datetime, you can use
ORDER BY MyDate, MyTime. With an index on(MyDate, MyTime)this should be ok. Range datetime queries would also be using that index.