Трябва да се върнете и да добавите ORDER BY
клаузи към вашия код, защото без тях поръчката никога не е гарантирана. Имахте „късмет“ в миналото, че винаги получавате една и съща поръчка, но това не е така, защото SQL Server 2008 така или иначе го гарантира. Най-вероятно е свързано с вашите индекси или как данните се съхраняват на диска.
Ако сте се преместили на нов хост, когато сте надстроили, разликата само в хардуерната конфигурация може да промени начина, по който се изпълняват вашите заявки. Да не говорим за факта, че новият сървър щеше да преизчисли статистиката за таблиците и оптимизаторът на заявки на SQL Server 2012 вероятно прави нещата малко по-различно от този в SQL Server 2008.
Заблуда е, че можете да разчитате на реда на набор от резултати в SQL, без изрично да посочвате реда, в който искате да го направите. SQL резултати НИКОГА имате поръчка, на която можете да разчитате, без да използвате ORDER BY
клауза. SQL е изграден около теорията на множеството. Резултатите от заявката са основно набори (или множество набори).
Ицик Бен-Ган дава добро описание на теорията на множеството по отношение на SQL в книгата си Microsoft SQL Server 2012 T-SQL Fundamentals
Теорията на множествата, която произхожда от математика Георг Кантор, е един от математическите клонове, на които се основава релационният модел. Дефиницията на Кантор за множество следва:
Под „набор“ разбираме всяка колекция M в цяло от определени, различни обекти m (които се наричат „елементи“ на M) на нашето възприятие или на нашата мисъл. - Джоузеф У. Даубен и Георг Кантор (PrincetonUniversity Press, 1990)
След задълбочено обяснение на термините в дефиницията Ицик продължава да казва:
Това, което дефиницията на Кантор за набор пропуска, вероятно е също толкова важно, колкото и това, което включва. Забележете, че дефиницията не споменава никакъв ред сред елементите на множеството. Редът, в който са изброени елементите на набора, не е важен. Формалната нотация за изброяване на множество елементи използва къдрави скоби:{a, b, c}. Тъй като поръчката няма значение, можете да изразите същия набор като {b, a, c} или {b, c, a}. Прескачайки напред към набора от атрибути (наречени колони в SQL), които съставляват заглавката на арелацията (наречена таблица в SQL), се предполага, че елементът трябва да бъде идентифициран по име, а не по редна позиция. По същия начин, разгледайте набора от кортежи (наречени редове от SQL), които съставляват тялото на релацията; даден елемент се идентифицира по ключовите си стойности - не по позиция. Много програмисти трудно се адаптират към идеята, че по отношение на заявките за таблици няма ред между редовете. С други думи, заявка към таблица може да върне редове в всякакъв ред освен ако не поискате изрично данните да бъдат сортирани по специфичен начин, може би за целите на представянето.
Но независимо от академичната дефиниция на набор, дори внедряването в SQL сървър никога не е гарантирало никакъв ред в резултатите. Тази публикация в блога на MSDN от 2005 г. от член на екипа за оптимизиране на заявки заявява, че изобщо не трябва да разчитате на поръчката от междинни операции.
Правилата за пренареждане могат и ще нарушат това предположение (и го правят, когато това е неудобно за вас, разработчика;). Моля, разберете, че когато пренареждаме операции, за да намерим по-ефективен план, можем да предизвикаме промяна на поведението на подреждане за междинни възли в дървото. Ако сте поставили операция в дървото, която предполага конкретно междинно подреждане, тя може да се счупи.
Тази публикация в блога на Conor Cunningham (архитект, SQL Server Core Engine) „Без предпазен колан – очаква се поръчка без ORDER BY“ е за SQL Server 2008. Той има таблица с 20k реда в нея с един индекс, който изглежда винаги връща редове в същия ред. Добавяне на ORDER BY
към заявката дори не променя плана за изпълнение, така че не е като добавянето на такъв да оскъпява заявката, ако оптимизаторът осъзнае, че не се нуждае от нея. Но след като добави още 20 000 реда към таблицата, изведнъж планът на заявката се променя и сега използва паралелизъм и резултатите вече не са подредени!
Трудната част тук е, че няма разумен начин всеки външен потребител да знае кога планът ще се промени. Пространството на всички планове е огромно и главата ви боли да размишлявате. Оптимизаторът на SQL Server ще промени плановете, дори за прости заявки, ако се променят достатъчно параметри. Може да имате късмет и да нямате промяна на плана, или просто да не мислите за този проблем и да добавите ПОРЪЧАЙТЕ ПО.
Ако имате нужда от повече убедителност, просто прочетете тези публикации:
- Без ORDER BY няма ред на сортиране по подразбиране. - Александър Кузнецов
- Ред в съда! - Томас Кайт
- Ред на набор от резултати в SQL – Тимъти Уайзман