Назад | Перейти на главную страницу

Изменения в порядке данных между SQL Server 2000 и 2012

Моя компания недавно перенесла веб-приложение .NET 1.1 / SQL Server 2000 на SQL Server 2012. У нас было несколько обращений в службу поддержки, связанных с необычным поведением, особенно с запросами хранимых процедур без предложений ORDER BY.

Я ценю, что функциональность, основанная на упорядочивании этих типов запросов, является плохой практикой, но знает ли кто-нибудь, есть ли официальная документация Microsoft об изменениях порядка по умолчанию между версиями SQL Server?

SQL Server 2012 не гарантирует порядок строк, возвращаемых в SQL 2012. Да и 2000, если на то пошло, тоже. (Цитата, которую я нашел для этого, на самом деле 2005 г., но достаточно близко.)

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

В основном: до сих пор тебе везло, и он тебя наконец укусил.

Эта статья Ицик Бен-Ган может вам помочь. Образец:

Один из наиболее важных аспектов множеств подразумевается в определении Кантора. Он не упоминает порядок элементов в наборе, потому что порядок не важен. Это одна из самых сложных концепций для понимания людьми при запросе таблицы, а именно понимание того, что нет никаких гарантий, что запрашиваемые данные будут использоваться в определенном порядке. Например, некоторые люди предполагают, что когда они запрашивают таблицу с кластеризованным индексом, они получат данные обратно в порядке кластерного индекса. С точки зрения языка это не гарантируется, потому что то, что вы запрашиваете, - это набор, а то, что вы получаете обратно, - это набор. SQL Server знает, что язык не предоставляет никаких гарантий упорядочения, поэтому он сканирует данные в любом порядке, в том числе не в порядке кластеризованного индекса. Люди часто используют методы, которые нарушают основанные на множествах и реляционные концепции в том смысле, что правильность результатов зависит от данных, потребляемых в порядке индекса, чего SQL Server никогда не гарантирует. Я освещаю пару классических примеров в своих эксклюзивных веб-статьях «Назначение многострочной переменной и ЗАКАЗАТЬ" и "Упорядоченное ОБНОВЛЕНИЕ и решения на основе наборов для запущенных агрегатов».

Бен-Ган написал SQL Server 70-461 учебник и подчеркивает этот момент.

Хотел бы я рассказать вам что-нибудь получше, но ... нет, нет "порядка по умолчанию", и поэтому вы не должны полагаться на него, и он не задокументирован.

Заказ наборов неопределенный и недокументированный. «Недокументированный» в данном случае означает две вещи:

  1. Мы не сможем предоставить вам конкретную ссылку или цитату с подробными сведениями об изменениях или о том, каким будет новое поведение, поскольку оно явно не заявлено. Это по дизайну, и в соответствии с концепцией реляционного «множества».
  2. Поскольку это не задокументировано, Microsoft может изменить поведение в любое время. В остальном ничем не примечательный патч, доставленный через Центр обновления Windows, может изменить это (не то, что он есть, а то, что мог без нарушения каких-либо политик). Даже если вы выявите определенное поведение сегодня, вам не следует полагаться на него, потому что завтра оно может измениться без предупреждения.

Эта свобода важна для таких поставщиков баз данных, как Microsoft. Это дает им возможность вводить новшества и вносить положительные изменения в свой продукт.

Это подводит меня к следующему пункту. Долгое время существовала идея, что запросы без предложения ORDER BY будут возвращать результаты в соответствии с первичным ключом (кластеризованным индексом) основной таблицы в запросе. Это ложный, и всегда было ложью. Результаты часто возвращаются таким образом, но только потому, что обычно это самый быстрый способ обслуживания запроса. Но всегда были исключения из этого: покрывающие индексы, циклическое сканирование таблиц, сложные соединения и подзапросы, где «основная» таблица запроса может изменяться в зависимости от того, какая статистика была собрана в этом месяце, и т. Д.

В последние годы новые концепции, такие как рекурсивные CTE, оконные функции и операции APPLY, создали множество новых ситуаций, в которых порядок кластеризованного индекса больше не является самым быстрым способом обслуживания запроса. Это влияние выходит за рамки простых запросов, в которых используются эти новые функции. По мере того, как механизм запросов усложняет работу с новыми функциями, он получает новые инструменты для поддержки этих функций, которые также полезны при подготовке планов для старых запросов.

Просто чтобы добавить больше В sql 2k8 enterprise есть новая функция, называемая mery go around.
Эта функция по сути повторного использования запроса сканирования таблицы из другого потока.
http://www.sanssql.com/2013/07/merry-go-round-scans-in-sql-server.html