As another user mentioned, these are all wild assumptions without seeing the query plan. But I would be surprised if the query used either an index anyway. Even if they span indexes, you filter the result of a window function in a subquery, the scheduler does not know for which rows the row_number function will return 100-110 until it analyzes the entire result set in sub, and you actually ordered a subquery by price, so it would not be of any use, using either an index. I canβt explain why this happens faster in the upstream case under these conditions, but we need to see a query plan in order to understand this, but I suspect that something else might be in the game.
It looks like you are performing a window function to implement swap, if so, and you are using 2012 or higher, try using offset / fetch, for example:
select b.* from Books b (nolock) inner join BookPublishRegions p (nolock) on b.BookKey = bp.BookKey where contains(p.PublishRegionName, 'France') order by price desc offset 100 fetch 10
The planner can understand that he can use the index. Although it probably should be a clustered or encompassing index in order to make any difference, to be honest.
If you are in 2008 or earlier, try placing an explicit order at the upper end of the subquery so that the scheduler understands that it can use the index. You can still use the window function and filter in the external query to make a search call, but in this way it will hopefully run the window function on a much smaller number of lines:
select * from ( select top 110 (row_number() over (ORDER BY b.Price DESC)) as RowNumber, b.* from Books b (nolock) inner join BookPublishRegions p (nolock) on b.BookKey = bp.BookKey where contains(p.PublishRegionName, 'France') ORDER BY b.Price DESC ) as t1 where t1.RowNumber between 100 and 110
EvilPuppetMaster
source share