First, why DBCC DROPCLEANBUFFERS;
? This is a hard cold reset of the buffer pool. Unless you want to measure and tune your hard drives IO performance, nobody cares about the performance of a cold cache. This is not how your system will work. Caching pages in the buffer pool is the most critical performance aspect in databases, and you take that out. Its like showing up in a Ferrari without the engine and asking why is so slow. For performance measurements you should do exactly the opposite: run he query 4-5 times to warm up the cache, then measure.
Second, what is your table structure? Is the table Account.Customer
table cluster index order by Record_id
? If no, you will never get the performance you want, no matter how you express your T-SQL.
And last but not least, what system do you have? Does it have enough RAM to cache the entire database in memory? If no, buy more RAM. Are there other processes that compete for memory, like IIS/Asp? If yes, kick them out to their own server, you should never ever run the database on the same host as the web server if performance is important.
For an alternative fast paging consider keyset driven solutions:
/* moving up */
SELECT top(@Page_Size) *
FROM Account.Customer
WHERE Record_Id > @lastPageRecordId
ORDER BY Record_Id;
/* moving down */
SELECT top(@Page_Size) *
FROM Account.Customer
WHERE Record_Id < @firstPageRecordId
ORDER BY Record_Id DESC;
A keyset driven solution can seek straight to the last position and then range scans the next/previous page, using the clustered index key position. The paging logic (state) must remember the last and first keys on the page being displayed in order to continue from there, instead of remembering the page number.
Rowcount based solutions (as well as LIMIT in MySQL) are less efficient than keyset based ones because they always have to count the records to position themselves, instead of seeking straight to the position as keysets can.