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?


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ć.


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

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,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.