2009-07-10 2 views
6

Una tabella è ordinata in base alla sua chiave primaria? Se ho una tabella con la chiave primaria su una colonna di identità BigInt posso fidarmi che le query restituiranno sempre i dati ordinati dalla chiave o devo esplicitamente aggiungere "ORDER BY". La differenza di prestazioni è significativa.Ordinamento chiavi primarie

risposta

11

I dati vengono archiviati fisicamente mediante un indice cluster, che di solito è la chiave primaria ma non deve essere.

Non è garantito che i dati in SQL abbiano ordine senza una clausola ORDER BY. Devi sempre specificare una clausola ORDER BY quando hai bisogno che i dati siano in un ordine particolare. Se la tabella è già ordinata in questo modo, l'ottimizzatore non eseguirà alcun lavoro aggiuntivo, quindi non c'è nulla di male nel trovarlo lì.

Senza una clausola ORDER BY, RDBMS potrebbe restituire pagine memorizzate nella cache che corrispondono alla query mentre attende che i record vengano letti dal disco. In tal caso, anche se esiste un indice sulla tabella, i dati potrebbero non entrare nell'ordine dell'indice. (Nota: questo è solo un esempio - non so o anche pensare che un mondo reale RDBMS farà questo, ma è un comportamento accettabile per un'implementazione SQL.)

EDIT

Se si dispone di un impatto sulle prestazioni durante l'ordinamento rispetto a quando non si ordina, probabilmente stai ordinando su una colonna (o una serie di colonne) che non ha un indice (in cluster o in altro modo). Dato che si tratta di una serie temporale, è possibile che si stia ordinando in base al tempo, ma l'indice cluster si trova sul bigint principale. SQL Server non sa che entrambi aumentano allo stesso modo, quindi deve ricorrere a tutto.

Se la colonna temporale e la colonna della chiave primaria sono correlate per ordine (una aumenta se e solo se l'altra aumenta o rimane uguale), ordina invece con la chiave primaria. Se non sono correlati in questo modo, sposta l'indice cluster dalla chiave primaria a qualsiasi colonna che stai ordinando.

+1

Il primo paragrafo dovrebbe indicare "I dati vengono archiviati fisicamente dall'indice cluster ...". Tutto il resto di Welbog dice che - solo perché è archiviato fisicamente [all'interno di ogni pagina] in un ordine non significa che lo recupererai in questo ordine. Anche la frammentazione del disco fisico potrebbe avere un impatto su questo. –

+0

@Philip Kelley: modificato per riflettere il tuo migliore fraseggio. Grazie. – Welbog

+0

Sto effettivamente ordinando la chiave primaria (che è il BigInt). I dati sono stati inseriti in modo ordinato (per data). –

0

In SQL Server: no, tramite la chiave di cluster - quale valore predefinito per la chiave primaria, ma non deve essere uguale.

La funzione principale della chiave primaria è identificare in modo univoco ogni riga della tabella, ma non implica alcun ordinamento (fisico) di per sé.

Non sono sicuro degli altri sistemi di database.

Marc

0

Questo può essere attuazione specifiche, ma MySQL sembra per ordinare la chiave primaria per impostazione predefinita. Tuttavia, ogni volta che è necessario garantire che le righe vengano ordinate in un determinato modo, è necessario aggiungere ORDER BY.

+0

solo se la chiave primaria è anche il CLUSTERING KEY - che è di default, ma NON DEVE essere ....... –

+0

Ah grazie è bello sapere. –

1

Una tabella di default non è 'cluster', cioè organizzata da PK. Hai la possibilità di specificarlo come tale. Quindi il valore predefinito è "HEAP" (in nessun ordine particolare) e l'opzione che si sta cercando è "CLUSTERED" (SQL Server, in Oracle è chiamato IOT).

  • Una tabella può avere un solo cluster (senso)
  • Utilizzare la PRIMARY KEY sintassi cluster della DDL
  • Ordina per PK deve ancora essere rilasciato sul vostro seleziona, il fatto di esso che è in cluster farà sì che la query di correre più veloce, come il piano di ottimizzatore saprà che non ha bisogno di fare la cernita su un indice cluster

il poster in precedenza è corretta, SQL (e la base teorica di esso) definisce in particolare un seleziona come set/tupla non ordinato.

SQL di solito cerca di rimanere nel regno logico e non fare ipotesi sull'organizzazione fisica/posizioni ecc. Dei dati. L'opzione CLUSTERED ci consente di farlo per situazioni di vita reale.

0

Quasi ogni volta che verrà ordinato dalle tabelle Identità. Esegue l'ordinamento in base all'indice cluster e non sempre può essere ordinato dall'identità, ma non l'ho mai visto non ordinato dall'ID identità quando si seleziona *. Qual è la ragione alla base della mancata specificazione di un ordine? Non vedo perché causi una differenza nelle prestazioni.

+0

Il motivo è puramente basato sulle prestazioni (vedi commento sopra). –

2

Senza un ORDER BY esplicito, non esiste un ordinamento predefinito. Una domanda molto comune Come tale, c'è una risposta in scatola: "La differenza di prestazioni è significativa"

Without ORDER BY, there is no default sort order.

Puoi dirci perché?

+0

I dati sono serie temporali e le query restituiscono mesi di dati. Senza l'ordine Dalla stored procedure è in grado di iniziare a restituire le righe in pochi secondi. Con Order By è fino a un minuto prima che la prima riga ritorni. –

+0

È possibile provare OPTION (FAST 1) http://msdn.microsoft.com/en-us/library/ms181714.aspx –

1

Per garantire un ordine, è necessario applicare ORDER BY. Se notate una differenza di prestazioni rispetto a quanto probabile, i vostri dati non sono stati ordinati senza il ORDER BY sul posto — altrimenti SQL-Server deve comportarsi male poiché non sta realizzando che i dati sono già ordinati. L'aggiunta di ORDER BY a dati già ordinati non dovrebbe comportare una penalizzazione delle prestazioni poiché l'RDBMS dovrebbe essere abbastanza intelligente da realizzare l'ordine dei dati.