У последовательностей много преимуществ перед IDENTITY, в частности они более гибкие, чем IDENTITY, и обеспечивают широкие возможности управления. Надеюсь, благодаря этой статье вы больше узнали о работе с последовательностями, а также о кэшировании, получении диапазона значений и формировании нескольких значений для одной целевой строки.

Типичный способ разбиения на страницы состоит в использовании функции ROW_ NUMBER. Однако такому решению свойственны неизбежные недостатки. В этой статье я приведу их описание и рекомендации по устранению. В примерах используется таблица Orders в базе данных PerformanceV3. Вы можете загрузить исходный текст для создания тестовой базы данных PerformanceV3 (http://tsql.solidq.com/books/source_ code/PerformanceV3.zip).

Существует некластеризован- ный, неохватывающий индекс PKOrders, определенный для таблицы Orders, с ключом orderid. К счастью, оптимизатор достаточно интеллектуален, чтобы выбрать план, который просматривает в индексе лишь строки, число которых равно верхнему номеру строки в нужном диапазоне. Таким образом, если число строк равно 1000, а размер страницы — 25, то план просматривает первые 25 000 строк в индексе и останавливается. Затем он фильтрует только последние 25 строк. Однако план также выполняет 25 000 уточняющих запросов вместо 25, что приводит к лишним уточняющим запросам. При запросе страницы № 1000 вы получаете 76978 операций считывания. Конечно, пользователи обычно не заходят так далеко, но чем больше глубина, тем больше обрабатывается лишних уточняющих запросов.

Простой прием, позволяющий предотвратить лишние уточняющие запросы, заключается в том, что внутренний запрос возвращает только ключ, который появляется в индексе. Затем внешний запрос выполняет объединение обобщенного табличного выражения (СТЕ) и таблицы, чтобы получить остальную информацию. В листинге 2 приведен полный исходный текст, реализующий этот прием. На рисунке 2 показан план данного решения.

Обратите внимание, что на этот раз совершается всего 25 сеансов поиска в индексе по orderid, за которыми следует 25 уточняющих запросов. Этот план выполняет 226 операций чтения благодаря тому, что фильтр применяется к плану перед выполнением поисков и уточняющих запросов.

Ни для кого не секрет, что разработчики не принимают во внимание проблемы масштабируемости, создавая решения, поддерживаемые SQL Server или другими реляционными базами данных. В самом деле, не так давно мне пришлось жаловаться на разработчиков, которые ошибочно считают NoSQL решением всех проблем, связанных с масштабируемостью и производительностью, с которыми они сталкиваются при создании приложений, основанных на реляционных базах данных. Тем не менее по моему опыту разработчикам проше всего прочувствовать проблемы, связанные с масштабируемостью, благодаря триггерам.