У опублікованому вами запиті:
select * from <table_name>;
Немає такого поняття, як 100-й-200-й рядки, оскільки ви не вказуєте ЗАМОВЛЕННЯ. Замовлення не гарантується, якщо ви не включите ЗАМОВЛЕННЯ за цілою низкою цікавих причин, але це насправді не в цьому суть.
Отже, щоб проілюструвати вашу думку, давайте скористаємося таблицею - я буду використовувати таблицю користувачів з дампу даних переповнення стека та запустіть цей запит:
SELECT * FROM dbo.Users ORDER BY DisplayName;
За замовчуванням у полі DisplayName немає індексу, тому SQL Server повинен сканувати всю таблицю, а потім сортувати її за DisplayName. Ось план виконання :
Це не дуже - це велика робота, орієнтовна вартість якого складе близько 30 тис. (Ви можете бачити це, якщо навести курсор миші на оператора вибору на PasteThePlan.) Що буде, якщо ми хочемо лише рядків 100-200? Ми можемо використовувати цей синтаксис у SQL Server 2012+:
SELECT * FROM dbo.Users ORDER BY DisplayName OFFSET 100 ROWS FETCH NEXT 100 ROWS ONLY;
План виконання щодо цього теж досить потворний:
SQL Server все ще сканує всю таблицю для складання відсортованого списку лише для того, щоб дати вам рядки 100-200, а вартість все ще становить близько 30 тис. Ще гірше, що весь цей список буде перебудовуватися щоразу, коли ваш запит запускається (адже зрештою, хтось міг змінити своє DisplayName.)
Щоб зробити це швидше, ми можемо створити некластеризований індекс на DisplayName, який є копією нашої таблиці, відсортованою за цим конкретним полем:
CREATE INDEX IX_DisplayName ON dbo.Users(DisplayName);
За допомогою цього індексу план виконання нашого запиту зараз шукає індекс:
Запит завершується миттєво і має орієнтовну вартість піддерева лише 0,66 (на відміну від 30 к).
Підсумовуючи це, якщо ви впорядковуєте дані таким чином, щоб підтримувати запити, які ви часто виконуєте, то так, SQL Server може приймати ярлики для швидшого запуску запитів. Якщо, з іншого боку, все, що ви маєте, це купи або кластеризовані індекси, ви накручені.