I have a table, and for a given set of fields a, b and c, I need to get the first and last rows ordered by d and e, and am using ROW_NUMBER to get these rows. The relevant part of the statement is...
ROW_NUMBER() OVER (PARTITION BY a,b,c ORDER BY d ASC, e ASC) AS row_number_start,
ROW_NUMBER() OVER (PARTITION BY a,b,c ORDER BY d DESC, e DESC) AS row_number_end
The execution plan shows two sort operations, one for each. These sort operations make up over 60% of the total cost of the statement (we're talking tens of millions of rows here, the partitions will usually have 1-100 records per partition, mostly under 10)
so it would be good if I could get rid of one of them. I tried to create an index to replicate the sort; this eliminated one of the sort operations but not the latter. (Note that any index created would only be of use for this process, and would be recreated daily as part of an ETL process.)
From inspecting the execution plan, I believe the problem is that when doing a partition by statement, SQL Server insists on ordering by the partitioning columns on an ascending basis. Logically it doesn't matter if you order ascending or descending, and if the optimiser understood this then it could just read the same index backwards to work out row_number_end.
Is there any way I can make the optimiser see sense here, or can someone suggest an alternative approach to reach the same end goal?