Implementazioni del database di ORDER BY in una sottoquery


10

Sto usando un'applicazione (MapServer - http://mapserver.org/ ) che avvolge le istruzioni SQL, in modo che l'istruzione ORDER BY sia nella query interna. Per esempio

SELECT * FROM (
        SELECT ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl

L'applicazione ha molti driver di database diversi. Uso principalmente il driver MS SQL Server e SQL Server 2008. Questo genera un errore se viene trovato un ORDER BY in una sottoquery.

Da MS Docs (anche se questo è per SQL Server 2000 sembra ancora applicarsi):

Quando si utilizza una clausola ORDER BY in una vista, una funzione incorporata, una tabella derivata o una sottoquery, non garantisce l'output ordinato. Invece, la clausola ORDER BY viene utilizzata solo per garantire che il set di risultati generato dall'operatore Top abbia una composizione coerente. La clausola ORDER BY garantisce un set di risultati ordinato solo quando è specificato nell'istruzione SELECT più esterna.

Tuttavia lo stesso tipo di query quando eseguito in Postgres (9) e Oracle restituisce risultati - con l'ordine come definito nella sottoquery. In Postgres il piano di query mostra che i risultati sono ordinati e le note di rilascio di Postgres includono l'articolo che implica che vengano utilizzati gli ordini di subquery:

Evita l'ordinamento quando la subquery ORDER BY corrisponde alla query superiore

http://en.wikipedia.org/wiki/Order_by afferma:

Sebbene alcuni sistemi di database consentano la specifica di una clausola ORDER BY nelle sottoselezioni o visualizzano le definizioni, la presenza non ha alcun effetto.

Tuttavia dal mio controllo dei piani di query:

  • SQL Server 2008 non supporta ORDER BY in una sottoquery
  • Postgres 9 supporta ORDER BY in una sottoquery
  • Oracle 10g supporta ORDER BY in una sottoquery

Quindi la mia domanda ci sono collegamenti che possono confermare o negare ufficialmente che Postgres e Oracle non consentono l'ordinamento in una sottoquery?


2
Solo perché si osservano determinati risultati non li garantisce. Se vuoi coerenza, metti l'ordine all'esterno. Periodo.
Aaron Bertrand

Idealmente questo è ciò che verrà implementato. Tuttavia, per arrivare a questa fase comporteranno modifiche alla logica principale e molti driver di database. Poiché questo problema non è stato segnalato da molti anni, sembra che alcuni dbs implementino costantemente ORDER BY nelle sottoquery. Sarebbe bello sapere quali se possibile.
geographika,

2
@geographika Anche se alcuni DBMS lo fanno in modo coerente fino ad ora, non vi è alcuna garanzia che continueranno a fare lo stesso in futuro. Ad esempio, i miglioramenti apportati a MySQL dall'ottimizzatore in 5.6 (e MariaDB 5.3) identificerebbero ORDER BYla subquery come ridondanti e non farebbero l'ordinamento non necessario.
ypercubeᵀᴹ

Risposte:


15

Dovrai fare in modo che la tua applicazione non inserisca la ORDER BYsubquery all'interno (forse ha un'opzione per non utilizzare una subquery inutile in primo luogo). Come hai già scoperto, questa sintassi non è supportata in SQL Server senza TOP. E con TOP, a meno che tu non voglia lasciare alcune righe fuori, usare TOP 100 PERCENTrenderà ORDER BYcomunque l' ottimizzato via.

E in Oracle e PostGres, solo perché la sintassi è supportata , non significa che sia rispettata. E solo perché lo osservi come obbedito in alcuni scenari, non significa che continuerà a essere obbedito man mano che escono nuove versioni o con sottili modifiche ai dati, alle statistiche, alla query stessa o all'ambiente.

Posso assicurarti che, senza dubbio , se desideri una garanzia sull'ordine, devi inserire la ORDER BYquery più esterna. Questa dovrebbe essere una dottrina che tieni vicino, indipendentemente dalla piattaforma che stai utilizzando.

Stai chiedendo un link che dichiari ufficialmente che qualcosa non è supportato. È come cercare nel manuale del proprietario dell'auto una dichiarazione ufficiale secondo cui la tua auto non può volare.


Grazie. Penso che MSSQL abbia l'approccio giusto nel lanciare un errore. Sia il supporto che l'implementazione dell'ordinamento su query interne, quando va contro un principio SQL di base, sembra una ricetta per il disastro. Non sono sicuro dell'analogia con l'auto - devi aggiungere cercandola nel manuale mentre l'auto sta effettivamente volando ..
geographika

-1

Devo ammettere che questo è squallido ma se sei in difficoltà prova a restituire il numero massimo di righe nella sottoquery. Restituire il primo 100 percento non funziona, ma se si desidera superare il problema è possibile eseguire una query sul numero di righe e passarlo a TOP come variabile. Ho provato questo su un database impostato sul livello di compatibilità 80 quindi penso che dovrebbe funzionare con SQL 2000.

SELECT * FROM (
        SELECT TOP (100000) ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl

L'ho provato inizialmente e mi è sembrato di sistemare bene piccoli set di dati. Tuttavia, quando ottenevo recordset molto grandi, l'ordinamento è diventato di nuovo casuale in SQL Server 2008R2. Forse si riferisce alle dimensioni di memoria / pagina?
geographika,

Mi dispiace, non ha aiutato. La selezione del primo 100 percento ha anche portato l'ordinamento a tornare a caso.
DBNull

Questo non funzionerà se la query diventa parallela, soprattutto se Namenon è univoca. Potrebbe non continuare a funzionare in serie se l'ottimizzatore sceglie un indice diverso, con un ordine di colonne chiave diverso.
Erik Darling,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.