Raketenwilli: Du hast Recht: Union ALL geht zwar mit Trick - bringt dann aber nichts mehr.

Beitrag lesen

(Die Tests habe ich mit MariaDB 10.5 und der öffentlich verfügbaren GN250-Datentabelle gemacht)

Use of ORDER BY for individual SELECT statements implies nothing about the order in which the rows appear in the final result because UNION by default produces an unordered set of rows.

Du hast Recht: Der Optimizer schmeisst das ORDER BY aus der Abfrage, es sei denn dieses ist mit LIMIT kombiniert:

  (SELECT
     NNID, Name
     FROM gn250
     WHERE Name !="Pilsdorf" ORDER BY Name
  )
UNION ALL
 (SELECT
     NNID, Name
     FROM gn250 where Name="Pilsdorf"
 )
LIMIT 10;

funktioniert NICHT, die Daten werden nicht sortiert („wie Kraut und Rüben“. Pilsdorf bleibt aber der letzte Eintrag.

Jetzt halte ich mich für ein nicht ganz doofes Kerlchen und denke mir: „Was? Du willst ein LIMIT? Du kriegst ein LIMIT!“. Ich weiß ja nach einer Zählung, dass die Datenbank 149745 Einträge hat und denke mir „Friss das hier“:

  (SELECT
     NNID, Name
     FROM gn250
     WHERE Name !="Pilsdorf" ORDER BY Name LIMIT 150000
  )
UNION ALL
 (SELECT
     NNID, Name
     FROM gn250 where Name="Pilsdorf"
 )

Das Ergebnis sieht gut aus (ist also wie erwartet sortiert). Bis auf den Umstand, das MariaDB wie folgt „nölt“:

149745 rows in set (0.554 sec)

Eine ganze halbe Sekunde? Das ist „viel“, weil das eine faktisch lastlose Datenbank auf einem sich totlachendem System ist.

Da wären also zwei getrennte Abfragen und die spätere Vereinigung des Ergebnisses z.B. im abfragenden PHP-Skript schneller…

EXPLAIN sagt dann für die Teilabfrage mit dem großen Ergebnis:

Using where; Using filesort. 

Der Vorteil des Nutzens des Indexes ist also weg.

Noch ein Nachtrag:

Auf die Idee, hilfsweise eine View zu bauen ...

CREATE VIEW gn250_by_name AS SELECT * FROM gn250 ORDER BY NAME;

und diese in der Abfrage zu benutzen bin ich auch gekommen:

Bringt nichts, Ergebnis wie im ersten Versuch, der Optimizer verwirft das ORDER. (Und das ohne Warnung oder Notiz!)