sql >> Database teknologi >  >> RDS >> Sqlserver

Standard rækkefølge i SELECT-forespørgsel - SQL Server 2008 vs SQL 2012

Du skal gå tilbage og tilføje ORDER BY klausuler til din kode, fordi uden dem er ordren aldrig garanteret. Du var "heldig" før i tiden, at du altid fik den samme ordre, men det var ikke fordi SQL Server 2008 garanterede det alligevel. Det havde højst sandsynligt at gøre med dine indekser eller hvordan dataene blev gemt på disken.

Hvis du flyttede til en ny vært, da du opgraderede, kunne forskellen i hardwarekonfiguration alene have ændret den måde, dine forespørgsler udføres på. For ikke at nævne det faktum, at den nye server ville have genberegnet statistik på tabellerne, og SQL Server 2012-forespørgselsoptimeringen gør sandsynligvis tingene en smule anderledes end den i SQL Server 2008.

Det er en fejlslutning, at du kan stole på rækkefølgen af ​​et resultatsæt i SQL uden eksplicit at angive den rækkefølge, du vil have det i. SQL-resultater ALDRIG har en ordre, du kan stole på uden at bruge en ORDER BY klausul. SQL er bygget op omkring mængdeteori. Forespørgselsresultater er grundlæggende set (eller multi-sæt).

Itzik Ben-Gan giver en god beskrivelse af mængdeteori i relation til SQL i sin bog Microsoft SQL Server 2012 T-SQL Fundamentals

Mængdeorien, som opstod hos matematikeren Georg Cantor, er en af ​​de matematiske grene, som relationsmodellen er baseret på. Cantors definition af et sæt er:

Med et "sæt" mener vi enhver samling M i en helhed af bestemte, distinkte genstande m (som kaldes "elementerne" af M) af vores opfattelse eller af vores tanke. - Joseph W. Dauben og Georg Cantor (PrincetonUniversity Press, 1990)

Efter en grundig forklaring af begreberne i definitionen fortsætter Itzik med at sige:

Det, Cantors definition af et sæt udelader, er nok lige så vigtigt, som det indeholder. Bemærk, at definitionen ikke nævner nogen rækkefølge blandt de indstillede elementer. Rækkefølgen, hvori sætelementerne er opført, er ikke vigtig. Den formelle notation for listesætelementer bruger krøllede parenteser:{a, b, c}. Fordi rækkefølge ikke har nogen relevans, kan du udtrykke det samme sæt som {b, a, c} eller {b, c, a}. Springer man frem til disse attributter (kaldet kolonner i SQL), der udgør headeren af ​​arelation (kaldet en tabel i SQL), formodes et element at blive identificeret ved navn - ikke ordinal position. Overvej på samme måde det sæt af tupler (kaldet rækker af SQL), der udgør kroppen af ​​relationen; et element identificeres ved dets nøgleværdier - ikke efter position. Mange programmører har svært ved at tilpasse sig tanken om, at der med hensyn til forespørgselstabeller ikke er nogen rækkefølge blandt rækkerne. Med andre ord kan en forespørgsel mod en tabel returnere rækker i en hvilken som helst rækkefølge medmindre du udtrykkeligt anmoder om, at dataene sorteres på en bestemt måde, måske til præsentationsformål.

Men uanset den akademiske definition af et sæt har selv implementeringen i SQL server aldrig garanteret nogen rækkefølge i resultaterne. Dette MSDN blogindlæg fra 2005 af et medlem af forespørgselsoptimeringsteamet siger, at du slet ikke bør stole på ordren fra mellemliggende operationer.

Ombestillingsreglerne kan og vil overtræde denne antagelse (og gør det, når det er ubelejligt for dig, udvikleren;)). Forstå venligst, at når vi omarrangerer operationer for at finde en mere effektiv plan, kan vi få bestillingsadfærden til at ændre sig for mellemliggende noder i træet. Hvis du har lagt en operation i træet, der antager adskilt mellemrækkefølge, kan den gå i stykker.

Dette blogindlæg af Conor Cunningham (arkitekt, SQL Server Core Engine) "No Seatbelt - Expecting Order without ORDER BY" handler om SQL Server 2008. Han har en tabel med 20.000 rækker i den med et enkelt indeks, der ser ud til altid at returnere rækker i samme rækkefølge. Tilføjelse af en ORDER BY til forespørgslen ændrer ikke engang udførelsesplanen, så det er ikke som at tilføje en gør forespørgslen dyrere, hvis optimizeren indser, at den ikke har brug for det. Men når han først føjer yderligere 20.000 rækker til tabellen, ændres forespørgselsplanen pludselig, og nu bruger den parallelisme, og resultaterne er ikke længere ordnet!

Den svære del her er, at der ikke er nogen rimelig måde for enhver ekstern bruger at vide, hvornår en plan vil ændre sig. Rummet for alle planer er enormt og gør ondt i dit hoved at tænke over. SQL Servers optimizer vil ændre planer, selv for simple forespørgsler, hvis nok af parametrene ændrer sig. Du kan være heldig og ikke have en planændring, eller du kan bare lade være med at tænke på dette problem og tilføje en BESTILLING AF.

Hvis du har brug for mere overbevisende, læs bare disse indlæg:

  • Uden ORDER BY er der ingen standard sorteringsrækkefølge. - Alexander Kuznetsov
  • Orden i retten! - Thomas Kyte
  • Rækkefølge af et resultatsæt i SQL - Timothy Wiseman



  1. Tjek, om en tabel har en TIMESTAMP-kolonne i SQL Server med OBJECTPROPERTY()

  2. Pivot ved hjælp af SQL Server 2000

  3. Hvilke metoder kan bruges til at administrere forskellige versioner af allerede eksisterende databaser?

  4. Hvordan håndteres to_date undtagelser i en SELECT-sætning for at ignorere disse rækker?