As ypercube commented
No, if the query is what you show, he is totally wrong. It's pretty sargable as it is.
You can verify this by:
- Creating a simple test table with a [Date] column.
- Insert a large number of rows with varying dates.
- NOTE: In the above "large number" and "varying dates" is a precaution to ensure that your query is selective enough. Otherwise the optimiser may choose not to use your index in any case.
- Generate a query plan for your query (once with an index on the Date column, and once without).
- You can also use STATISTICS IO to show the difference.
- If you have enough test data, the difference will be easily observable.
Once you've got the evidence, I suggest you do take it up with the DBA. However, don't get into an argument. Just show the test and data that demonstrates the index is used.
The point is you don't want to be forced to bend over backwards to avoid non-existant issues.
Fortunately in the case you demonstrated it won't be a problem to move the functions outside the query. E.g.
DECLARE @FromDate date ='inputdate',
@ToDate date = DATEADD(day, 1, @FromDate)
In fact, the above may even be more maintainable in the long run.
However, there will come a time when you have something that cannot be trivially changed according to the DBA's wishes. Such as:
--Granted this probably belongs in a JOIN clause, but is primarily for illustrative purposes.
--Also the issue of sargability applies just as much to JOIN clauses as WHERE clauses
WHERE a.date >= b.date
AND a.date < DATEADD(day, 1, b.date)
The only way to get this function out of the WHERE clause would be to precalculate another column
b.NextDay. Which is exactly why you need the DBA's to understand Sargability correctly. I.e. that the above:
- Would be able to leverage an index on
- But not be able to leverage an index on
- So the most selective column/index should not have a function applied, but the other can.
- Attempting to hack a solution without a function in the WHERE clause will reduce both maintainability and performance.
If you really can't get buy-in from the DBA's perhaps the following will work and bypass their cargo-cult rules:
;WITH CTE_B AS (
SELECT b.Date, DATEADD(day, 1, b.DATE) AS NextDay
WHERE a.Date >= CTE_B.Date
AND a.Date < CTE_B.NextDay
The optimiser will almost certainly optimise this in the same way as if the function were in the
WHERE clause, so you shouldn't get a performance knock. But it's certainly an unnecessary reduction in maintainability.