Quando si utilizza una ORDER BY
clausola all'interno di una query secondaria utilizzata insieme a un UNION
mysql, ottimizzerà il fileORDER BY
clausola .
Questo perché per impostazione predefinita a UNION
restituisce una lista non ordinata quindi quindi un fileORDER BY
non farebbe nulla.
L'ottimizzazione è menzionata nei documenti e dice:
Per applicare ORDER BY o LIMIT a un singolo SELECT, inserisci la clausola tra parentesi che racchiudono SELECT:
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
Tuttavia, l'uso di ORDER BY per singole istruzioni SELECT non implica nulla riguardo all'ordine in cui le righe vengono visualizzate nel risultato finale perché UNION per impostazione predefinita produce un insieme di righe non ordinato. Pertanto, l'uso di ORDER BY in questo contesto è tipicamente in congiunzione con LIMIT, in modo che venga utilizzato per determinare il sottoinsieme delle righe selezionate da recuperare per SELECT, anche se non influisce necessariamente sull'ordine di quelle righe nel risultato finale UNION. Se ORDER BY appare senza LIMIT in una SELECT, è ottimizzato perché non avrà comunque alcun effetto.
L'ultima frase di questo è un po 'fuorviante perché dovrebbe avere un effetto. Questa ottimizzazione causa un problema quando ci si trova in una situazione in cui è necessario ordinare all'interno della sottoquery.
Per forzare MySQL a non eseguire questa ottimizzazione, puoi aggiungere una clausola LIMIT in questo modo:
(SELECT 1 AS rank, id, add_date FROM my_table WHERE distance < 5 ORDER BY add_date LIMIT 9999999999)
UNION ALL
(SELECT 2 AS rank, id, add_date FROM my_table WHERE distance BETWEEN 5 AND 15 ORDER BY rank LIMIT 9999999999)
UNION ALL
(SELECT 3 AS rank, id, add_date from my_table WHERE distance BETWEEN 5 and 15 ORDER BY id LIMIT 9999999999)
Un alto LIMIT
significa che potresti aggiungere un OFFSET
sulla query complessiva se vuoi fare qualcosa come l'impaginazione.
Questo ti dà anche l'ulteriore vantaggio di poter ORDER BY
disporre di colonne diverse per ogni unione.