Implementacje baz danych ORDER BY w podzapytaniu

10

Korzystam z aplikacji (MapServer - http://mapserver.org/ ), która otacza instrukcje SQL, dzięki czemu instrukcja ORDER BY znajduje się w wewnętrznym zapytaniu. Na przykład

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

Aplikacja ma wiele różnych sterowników baz danych. Używam głównie sterownika MS SQL Server i SQL Server 2008. Zgłasza to błąd, jeśli w podzapytaniu zostanie znalezione polecenie ORDER BY.

Z MS Docs (choć dotyczy to SQL Server 2000, nadal wydaje się, że ma zastosowanie):

Kiedy używasz klauzuli ORDER BY w widoku, funkcji wbudowanej, tabeli pochodnej lub podzapytaniu, nie gwarantuje to uporządkowanego wyniku. Zamiast tego klauzula ORDER BY służy jedynie do zagwarantowania, że ​​zestaw wyników generowany przez górny operator ma spójny skład. Klauzula ORDER BY gwarantuje uporządkowany zestaw wyników tylko wtedy, gdy jest określony w najbardziej zewnętrznej instrukcji SELECT.

Jednak ten sam typ zapytania uruchamiany w Postgres (9) i Oracle zwraca wyniki - z kolejnością zdefiniowaną w podzapytaniu. W Postgres plan zapytań pokazuje, że wyniki są posortowane, a informacje o wydaniu Postgres zawierają element, który sugeruje, że używane są zamówienia na zapytania częściowe:

Unikaj sortowania, gdy podzapytanie ORDER BY pasuje do górnego zapytania

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

Chociaż niektóre systemy baz danych zezwalają na określenie klauzuli ORDER BY w podselekcjach lub definicjach widoków, obecność nie ma żadnego efektu.

Jednak z własnego sprawdzenia planów zapytań:

  • SQL Server 2008 nie obsługuje ORDER BY w podzapytaniu
  • Postgres 9 obsługuje ORDER BY w podzapytaniu
  • Oracle 10g obsługuje ORDER BY w podzapytaniu

Więc moje pytanie: czy są jakieś linki, które mogą oficjalnie potwierdzić lub zaprzeczyć, że Postgres i Oracle nie pozwalają na sortowanie w podzapytaniu?

geografia
źródło
2
To, że obserwujesz pewne wyniki, nie gwarantuje ich. Jeśli chcesz zachować spójność, umieść zamówienie na zewnątrz. Kropka.
Aaron Bertrand
Idealnie właśnie to zostanie wdrożone. Jednak przejście do tego etapu będzie wymagało zmian w podstawowej logice i wielu sterownikach baz danych. Ponieważ ten problem nie był zgłaszany przez wiele lat, wydaje się, że niektóre dbs konsekwentnie implementują ORDER BY w podzapytaniach. Byłoby miło wiedzieć, które z nich, jeśli to możliwe.
geographika
2
@geographika Nawet jeśli niektóre DBMS robią to konsekwentnie do tej pory, nie ma gwarancji, że będą robić to samo w przyszłości. Jako przykład, ulepszenia MySQL w optymalizatorze w 5.6 (i MariaDB 5.3) zidentyfikowałyby ORDER BYpodzapytanie jako nadmiarowe i nie dokonywałyby niepotrzebnego sortowania.
ypercubeᵀᴹ

Odpowiedzi:

15

Musisz sprawić, aby aplikacja nie wstawiała ORDER BYwewnętrznego podzapytania (być może ma opcję, aby nie używać niepotrzebnego podkwerendy). Jak już odkryłeś, ta składnia nie jest obsługiwana w SQL Server bez TOP. I za pomocą TOP, o ile nie chcesz pozostawić niektórych wierszy, użycie TOP 100 PERCENTspowoduje wyświetlenieORDER BY zrezygnowanie optymalizacji.

A w Oracle i PostGres tylko dlatego, że obsługiwana jest składnia , nie oznacza, że ​​jest ona przestrzegana. I tylko dlatego, że w niektórych scenariuszach jest to przestrzegane, nie oznacza to, że będzie ono nadal przestrzegane, gdy pojawią się nowe wersje lub z subtelnymi zmianami w danych, statystykach, samym zapytaniu lub środowisku.

Zapewniam cię, że bez wątpienia , jeśli potrzebujesz gwarancji na zamówienie, musisz złożyćORDER BY zapytanie zewnętrzne. To powinna być doktryna, którą trzymasz blisko, bez względu na to, jakiej platformy używasz.

Pytasz o link, który oficjalnie stwierdza, że ​​coś nie jest obsługiwane. To jest jak szukanie w instrukcji obsługi samochodu oficjalnego oświadczenia, że ​​twój samochód nie może latać.

Aaron Bertrand
źródło
Dzięki. Myślę, że MSSQL ma właściwe podejście do zgłaszania błędów. Zarówno obsługa, jak i wdrażanie sortowania w wewnętrznych zapytaniach, gdy jest ono sprzeczne z podstawową zasadą SQL, wydaje się receptą na katastrofę. Nie jestem jednak pewien co do analogii samochodu - należy dodać szukanie go w instrukcji, podczas gdy samochód faktycznie leci ..
geographika
-1

Przyznaję, że jest to obleśne, ale jeśli masz problemy, spróbuj zwrócić najwyższą liczbę wierszy w podzapytaniu. Zwracanie 100% najlepszych nie działa, ale jeśli chcesz przejść przez problem, możesz sprawdzić liczbę wierszy i przekazać ją do TOP jako zmienną. Przetestowałem to na bazie danych ustawionej na poziom zgodności 80, więc myślę, że powinna działać z SQL 2000.

SELECT * FROM (
        SELECT TOP (100000) ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl
DBNull
źródło
Próbowałem tego pierwotnie i wydawało się, że dobrze to sortuje dla małych zestawów danych. Jednak gdy otrzymywałem bardzo duże zestawy rekordów, sortowanie stało się ponownie losowe w SQL Server 2008R2. Może dotyczy pamięci / rozmiarów stron?
geographika
Przepraszam, to nie pomogło. Wybranie najwyższych 100 procent spowodowało również, że sortowanie powróciło do losowości.
DBNull
To nie zadziała, jeśli zapytanie przejdzie równolegle, zwłaszcza jeśli Namenie jest unikalne. Może nie działać seryjnie, jeśli optymalizator wybierze inny indeks o innej kolejności kolumn klucza.
Erik Darling,