sql >> Databáze >  >> RDS >> Sqlserver

Výchozí pořadí řádků ve SELECT dotazu - SQL Server 2008 vs SQL 2012

Musíte se vrátit a přidat ORDER BY doložky do vašeho kódu, protože bez nich není objednávka nikdy zaručena. V minulosti jste měli „štěstí“, že jste vždy dostali stejnou objednávku, ale nebylo to proto, že ji SQL Server 2008 tak jako tak zaručil. Nejpravděpodobněji to mělo co do činění s vašimi indexy nebo s tím, jak byla data uložena na disku.

Pokud jste se při upgradu přesunuli na nového hostitele, samotný rozdíl v konfiguraci hardwaru mohl změnit způsob provádění vašich dotazů. Nemluvě o tom, že nový server by přepočítal statistiky v tabulkách a optimalizátor dotazů SQL Server 2012 pravděpodobně dělá věci trochu jinak než ten v SQL Server 2008.

Je chybou, že se můžete spolehnout na pořadí sady výsledků v SQL, aniž byste výslovně uvedli pořadí, ve kterém je chcete mít. Výsledky SQL NIKDY mít objednávku, na kterou se můžete spolehnout bez použití ORDER BY doložka. SQL je postaven na teorii množin. Výsledky dotazů jsou v podstatě množiny (nebo více množin).

Itzik Ben-Gan poskytuje dobrý popis teorie množin ve vztahu k SQL ve své knize Microsoft SQL Server 2012 T-SQL Fundamentals

Teorie množin, která vznikla u matematika Georga Cantora, je jednou z matematických větví, na kterých je založen relační model. Cantorova definice množiny je následující:

„Souborem“ rozumíme jakýkoli soubor M do celku určitých, odlišných objektů m (které se nazývají „prvky“ M) našeho vnímání nebo našeho myšlení. – Joseph W. Dauben a Georg Cantor (PrincetonUniversity Press, 1990)

Po důkladném vysvětlení pojmů v definici Itzik pokračuje slovy:

To, co Cantorova definice množiny vynechává, je pravděpodobně stejně důležité jako to, co obsahuje. Všimněte si, že definice nezmiňuje žádné pořadí mezi prvky sady. Pořadí, ve kterém jsou prvky sady uvedeny, není důležité. Formální zápis pro výpis prvků množiny používá složené závorky:{a, b, c}. Protože pořadí nemá žádnou relevanci, můžete vyjádřit stejnou množinu jako {b, a, c} nebo {b, c, a}. Skočením dopředu k množině atributů (v SQL nazývaných sloupce), které tvoří hlavičku relace (v SQL nazývané tabulka), se předpokládá, že prvek bude identifikován jménem – nikoli ordinální pozicí. Podobně zvažte sadu n-tic (nazývaných pomocí SQL řádky), které tvoří tělo vztahu; prvek je identifikován svými klíčovými hodnotami, nikoli pozicí. Mnoho programátorů se jen těžko přizpůsobuje myšlence, že pokud jde o dotazování v tabulkách, mezi řádky není žádné pořadí. Jinými slovy, dotaz na tabulku může vrátit řádky v jakémkoli pořadí pokud výslovně nepožadujete, aby byla data roztříděna konkrétním způsobem, třeba pro účely prezentace.

Ale bez ohledu na akademickou definici množiny ani implementace v SQL serveru nikdy nezaručila pořadí ve výsledcích. Tento příspěvek na blogu MSDN z roku 2005 od člena týmu optimalizátoru dotazů uvádí, že byste se vůbec neměli spoléhat na pořadí z mezioperačních operací.

Pravidla pro přeskupování mohou a budou tento předpoklad porušovat (a dělají to, když je to pro vás, vývojáře nepohodlné;). Pochopte prosím, že když změníme pořadí operací, abychom nalezli efektivnější plán, můžeme způsobit, že se chování řazení změní pro mezilehlé uzly ve stromu. Pokud jste do stromu umístili operaci, která předpokládá konkrétní mezilehlé uspořádání, může se zlomit.

Tento blogový příspěvek od Conora Cunninghama (architekt, SQL Server Core Engine) „No Seatbelt – Expecting Order without ORDER BY“ je o SQL Server 2008. Má tabulku s 20 000 řádky s jediným indexem, který, jak se zdá, vždy vrací řádky v stejné pořadí. Přidání ORDER BY Dotazu se ani nezmění plán provádění, takže to není jako přidání jednoho do dotazu prodraží, pokud si optimalizátor uvědomí, že to nepotřebuje. Jakmile však do tabulky přidá dalších 20 000 řádků, plán dotazů se náhle změní a nyní používá paralelismus a výsledky již nejsou seřazeny!

Nejtěžší na tom je, že pro externího uživatele neexistuje žádný rozumný způsob, jak zjistit, kdy se plán změní. Prostor všech plánů je obrovský a bolí vás hlava z přemítání. Optimalizátor SQL Serveru změní plány, a to i pro jednoduché dotazy, pokud se změní dostatek parametrů. Můžete mít štěstí a nezměníte plán, nebo na tento problém prostě nemůžete myslet a přidat OBJEDNÁVKU BY.

Pokud potřebujete více přesvědčivosti, přečtěte si tyto příspěvky:

  • Bez ORDER BY neexistuje žádné výchozí pořadí řazení. - Alexandr Kuzněcov
  • Řeďte u soudu! - Thomas Kyte
  • Pořadí sady výsledků v SQL – Timothy Wiseman



  1. Jak ADDDATE() funguje v MariaDB

  2. Android SQLite Query – získávání posledních 10 záznamů

  3. Co se vlastně děje s tím hledáním?

  4. Jak exportovat data serveru SQL z tabulky do souboru CSV