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

Ordine delle righe predefinito nella query SELECT - SQL Server 2008 vs SQL 2012

Devi tornare indietro e aggiungere ORDER BY clausole al tuo codice perché senza di esse l'ordine non è mai garantito. In passato sei stato "fortunato" a ricevere sempre lo stesso ordine, ma non perché SQL Server 2008 lo garantisse comunque. Molto probabilmente aveva a che fare con i tuoi indici o con il modo in cui i dati venivano archiviati sul disco.

Se sei passato a un nuovo host quando hai aggiornato, la sola differenza nella configurazione hardware potrebbe aver cambiato il modo in cui le tue query vengono eseguite. Per non parlare del fatto che il nuovo server avrebbe ricalcolato le statistiche sulle tabelle e Query Optimizer di SQL Server 2012 probabilmente fa le cose in modo leggermente diverso da quello di SQL Server 2008.

È un errore che puoi fare affidamento sull'ordine di un set di risultati in SQL senza dichiarare esplicitamente l'ordine in cui lo desideri. Risultati SQL MAI avere un ordine su cui fare affidamento senza utilizzare un ORDER BY clausola. SQL è costruito attorno alla teoria degli insiemi. I risultati della query sono fondamentalmente insiemi (o multi-insiemi).

Itzik Ben-Gan fornisce una buona descrizione della teoria degli insiemi in relazione a SQL nel suo libro Microsoft SQL Server 2012 T-SQL Fundamentals

La teoria degli insiemi, nata con il matematico Georg Cantor, è una delle branche matematiche su cui si basa il modello relazionale. La definizione di Cantor di un insieme segue:

Per "insieme" intendiamo qualsiasi insieme M in un insieme di oggetti m definiti e distinti (che sono chiamati gli "elementi" di M) della nostra percezione o del nostro pensiero. - Joseph W. Dauben e Georg Cantor (Princeton University Press, 1990)

Dopo un'approfondita spiegazione dei termini nella definizione Itzik prosegue dicendo:

Ciò che la definizione di un insieme di Cantor tralascia è probabilmente importante quanto ciò che include. Si noti che la definizione non menziona alcun ordine tra gli elementi dell'insieme. L'ordine in cui sono elencati gli elementi dell'insieme non è importante. La notazione formale per elencare gli elementi dell'insieme usa le parentesi graffe:{a, b, c}. Poiché l'ordine non ha rilevanza, puoi esprimere lo stesso insieme di {b, a, c} o {b, c, a}. Passando all'insieme di attributi (chiamati colonne in SQL) che costituiscono l'intestazione di arelation (chiamati tabella in SQL), si suppone che un elemento venga identificato per nome, non per posizione ordinale. Allo stesso modo, considera l'insieme di tuple (chiamate righe da SQL) che costituiscono il corpo della relazione; un elemento è identificato dai suoi valori chiave, non dalla posizione. Molti programmatori hanno difficoltà ad adattarsi all'idea che, rispetto alle tabelle di interrogazione, non c'è ordine tra le righe. In altre parole, una query su una tabella può restituire righe in qualsiasi ordine a meno che tu non richieda espressamente che i dati siano ordinati in un modo specifico, magari a fini di presentazione.

Ma a prescindere dalla definizione accademica di un insieme anche l'implementazione in SQL server non ha mai garantito alcun ordine nei risultati. Questo post del blog MSDN del 2005 di un membro del team di Query Optimizer afferma che non dovresti assolutamente fare affidamento sull'ordine delle operazioni intermedie.

Le regole di riordino possono e violeranno questo presupposto (e farlo quando è scomodo per te, lo sviluppatore;). Ti preghiamo di comprendere che quando riordiniamo le operazioni per trovare un piano più efficiente, possiamo far cambiare il comportamento di ordinamento per i nodi intermedi nell'albero. Se hai inserito un'operazione nell'albero che presuppone un particolare ordinamento intermedio, può interrompersi.

Questo post sul blog di Conor Cunningham (Architect, SQL Server Core Engine) "No Seatbelt - Expecting Order without ORDER BY" riguarda SQL Server 2008. Ha una tabella con 20.000 righe con un singolo indice che sembra restituire sempre righe in lo stesso ordine. Aggiunta di un ORDER BY alla query non cambia nemmeno il piano di esecuzione, quindi non è come aggiungerne uno rende la query più costosa se l'ottimizzatore si rende conto che non ne ha bisogno. Ma una volta che aggiunge altre 20.000 righe alla tabella, improvvisamente il piano di query cambia e ora utilizza il parallelismo e i risultati non sono più ordinati!

La parte difficile qui è che non c'è alcun modo ragionevole per qualsiasi utente esterno di sapere quando un piano cambierà. Lo spazio di tutti i piani è enorme e ti fa male la testa a riflettere. L'ottimizzatore di SQL Server cambierà i piani, anche per query semplici, se una quantità sufficiente di parametri cambia. Potresti essere fortunato e non avere una modifica del piano, oppure puoi semplicemente non pensare a questo problema e aggiungere un ORDINE PER.

Se hai bisogno di essere più convincente, leggi questi post:

  • Senza ORDER BY, non esiste un ordinamento predefinito. - Aleksandr Kuznetsov
  • Ordine in tribunale! - Thomas Kyte
  • Ordine di un insieme di risultati in SQL - Timothy Wiseman