2010-07-17 12 views
9

Nel libro Inside Microsoft SQL Server ™ 2005 T-SQL Interrogazione, l'autore Itzik Ben-Gan ci dicono l'ordine o SQL Server di elaborazione query logica 2005 è:Confuso su Logical ordine Query Processing Itzik Ben-Gan nel suo SQL Server 2005 libro e SQL Server 2008 libro

(8) SELECT (9) DISTINCT (11) <TOP_specification> <select_list> 
(1) FROM <left_table> 
(3)  <join_type> JOIN <right_table> 
(2)  ON <join_condition> 
(4) WHERE <where_condition> 
(5) GROUP BY <group_by_list> 
(6) WITH {CUBE | ROLLUP} 
(7) HAVING <having_condition> 
(10) ORDER BY <order_by_list> 

1. FROM 
2. ON 
3. OUTER (join) 
4. WHERE 
5. GROUP BY 
6. CUBE | ROLLUP 
7. HAVING 
8. SELECT 
9. DISTINCT 
10. ORDER BY <---------------------- NOTE 
11. TOP  <---------------------- NOTE 

Nel suo libro Inside Microsoft SQL Server 2008: T-SQL interrogazione, ci ha detto il seguente ordine logico di elaborazione delle query:

(1) FROM 
(1-J1) Cartesian Product 
(1-J2) ON Filter 
(1-J3) Add Outer Rows 
(2) WHERE 
(3) GROUP BY 
(4) HAVING 
(5) SELECT 
(5-1) Evaluate Expressions 
(5-2) DISTINCT 
(5-3) TOP  <---------------------- NOTE 
(6) ORDER BY <---------------------- NOTE 

Nota l'ordine di TOP e ORDER BY negli estratti superiori da questi libri. Sono proprio di fronte. Penso che questi due passaggi siano molto importanti e daranno un risultato completamente diverso con un ordine diverso. Voglio sapere se SQL Server 2008 ha modificato qualcosa nel suo motore di archiviazione da SQL Server 2005 o qualcos'altro causa questo?

Grazie.

risposta

6

L'ordine di elaborazione logico è anche documentato in questa voce Books Online. Fare attenzione a distinguere ordine di elaborazione logico da ordine di elaborazione fisico. Come le note di entrata BOL:

I passaggi seguenti mostrano l'ordine di elaborazione logica, o vincolante ordine, per un'istruzione SELECT. Questo ordine determina quando gli oggetti definiti in una fase vengono resi disponibili alle clausole nelle successive fasi . Ad esempio, se il processore di query è in grado di associare (accedere) alle tabelle o alle viste definite nella clausola FROM, questi oggetti e le relative colonne vengono resi disponibili per tutti i passaggi successivi. Al contrario, poiché la clausola SELECT è il punto 8, qualsiasi alias di colonna o derivate colonne definite in tale clausola non possono essere referenziate dalle precedenti clausole . Tuttavia, è possibile fare riferimento a clausole successive come nella clausola ORDER BY. Si noti che l'esecuzione fisica effettiva dell'istruzione è determinata dal processore di query e l'ordine può variare da da questo elenco.

Query Optimizer è libera di traslare il requisito logica specificata dalla query in nessuna fisico piano di esecuzione che produce i risultati corretti. Generalmente, ci sono molte alternative fisiche per una determinata query logica, quindi è abbastanza normale che un piano fisico differisca fondamentalmente dall'ordine di elaborazione logica (per scopi vincolanti) descritto sopra.

5

Verificare this out - è un'esposizione a questo problema - e il libro di Itzik è menzionato. Il secondo ordine sopra è corretto.

+2

Si noti che il TOP utilizza l'ordine BY per determinare le righe da conservare. Questo è il modello logico di elaborazione, quindi ottenere i record TOP n basati su ORDER BY _logically_ non risulta in un set di righe con un ordine particolare: la fase logica ORDER BY ordina i risultati. In termini di elaborazione fisica, l'ORDINE BY verrebbe eseguito prima del TOP n. –

3

Nel suo 2015 rilascio di T-SQL Querying, Itzik Ben-Gan ha aggiornato l'elaborazione delle query logica nella "Lista 1-1 numeri step di query-elaborazione logica" come questo:

(5) SELECT (5-2) DISTINCT (7) TOP(<top_specification>) (5-1) <select_list> 
(1) FROM (1-J) <left_table> <join_type> JOIN <right_table> ON <on_predicate> 
     | (1-A) <left_table> <apply_type> APPLY <right_input_table> AS <alias> 
     | (1-P) <left_table> PIVOT(<pivot_specification>) AS <alias> 
     | (1-U) <left_table> UNPIVOT(<unpivot_specification>) AS <alias> 
(2) WHERE <where_predicate> 
(3) GROUP BY <group_by_specification> 
(4) HAVING <having_predicate> 
(6) ORDER BY <order_by_list> 
(7) OFFSET <offset_specification> ROWS FETCH NEXT <fetch_specification> ROWS ONLY; 

A differenza della precedente versione 2008 del libro, ORDER BY (passaggio 6) ora si verifica prima di TOP (passo 7). Naturalmente, come affermato altrove, i due sono correlati. Come Itzik spiega a pagina 6 di T-SQL Querying:

[TOP] filtra il numero specificato di righe basato sul ordinamento nella clausola ORDER BY, o sulla base di ordine arbitrario se un ORDER BY è assente. Con OFFSET-FETCH, questa fase salta il numero di righe specificato da e quindi filtra il successivo numero specificato di righe, in base all'ordine nella clausola ORDER BY.

Capire le fasi di elaborazione della query logica sopra è importante perché spiega stranezze altrimenti non intuitive in SQL.

Per esempio, non è possibile utilizzare un alias dal SELECT clausola (passo 5-2) nella clausola di WHERE (passo 2) perché il motore di espressione viene valutata la clausola WHERE prima della clausola di SELECT.

-- This won't work! 
SELECT Cost = Quantity * Price 
FROM Orders 
WHERE Cost > 500.00; 

Come Itzik dice nel suo libro, "Le fasi della elaborazione logica di una query hanno un ordine specifico. Al contrario, l'ottimizzatore spesso può fare scorciatoie nel piano di esecuzione fisica che esso genera. Di Ovviamente, farà scorciatoie solo se il set di risultati è quello corretto ".

Problemi correlati