L'aspetto di un set di risultati ordinato, senza una ORDER BY
clausola, spesso deriva da una scansione che recupera le righe in ordine di indice. Uno dei motivi per cui una scansione dell'ordine degli indici viene generalmente scelta sotto il READ COMMITTED
livello di isolamento predefinito è che riduce le possibilità di anomalie di concorrenza indesiderate come incontrare più volte la stessa riga o saltare completamente alcune righe. Questo è dettagliato in diversi punti, incluso in questa serie di articoli sui livelli di isolamento.
Con un NOLOCK
suggerimento sulla tabella, questo comportamento è rilassato e l'accesso alla tabella viene eseguito con il READ UNCOMMITTED
livello di isolamento più tollerante , che può eseguire la scansione dei dati in ordine di allocazione anziché in ordine di indice. Come descritto in quel collegamento, la decisione sull'utilizzo di una scansione dell'ordine di allocazione o dell'ordine dell'indice viene lasciata al motore di archiviazione. Questa scelta può cambiare tra le esecuzioni senza una modifica nel piano di query .
Questo può sembrare molto astratto, ma può essere più facilmente dimostrato con alcune query che utilizzano funzioni non documentate sul database AdventureWorks2012 .
USE AdventureWorks2012;
GO
-- Appears to be ordered by BusinessEntityID
-- File:Page:Slot goes up and down several times
-- Show physical locations with sys.fn_PhysLocFormatter (undocumented)
SELECT
P.BusinessEntityID,
[(File:Page:Slot)] =
sys.fn_PhysLocFormatter(%%physloc%%)
FROM Person.Person AS P;
-- Same query with TABLOCK or NOLOCK
-- Allocation-order (IAM) scan
-- Now appears to be ordered by File:Page:Slot instead of BusinessEntityID
SELECT P.BusinessEntityID,
[(File:Page:Slot)] =
sys.fn_PhysLocFormatter(%%physloc%%)
FROM Person.Person AS P WITH (NOLOCK);
Le domande sono prese in prestito con lievi modifiche da Paul White .
Infine, per essere chiari, questa risposta riguarda l' aspetto di un set di risultati ordinato. Non esiste un ordine di presentazione garantito senza un livello superiore ORDER BY
.
Una scansione dell'ordine di allocazione può verificarsi in una varietà di altre circostanze, ad esempio quando viene acquisito un blocco a livello di tabella o il database è in modalità di sola lettura. Il parallelismo può anche influenzare l'ordine in cui vengono restituiti i dati. Il punto chiave è che senza ORDER BY
, i dati dell'ordine in cui vengono restituiti possono variare nel tempo in base alla progettazione.