Saat Anda menggunakan ORDER BYklausa di dalam sub kueri yang digunakan bersama dengan UNIONmysql akan mengoptimalkan ORDER BYklausa tersebut.
Ini karena secara default a UNIONmengembalikan daftar tidak berurutan sehingga oleh karena itu an ORDER BYtidak akan melakukan apa-apa.
Pengoptimalan disebutkan di dokumen dan mengatakan:
Untuk menerapkan ORDER BY atau LIMIT ke SELECT individu, tempatkan klausa di dalam tanda kurung yang mengapit 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);
Namun, penggunaan ORDER BY untuk pernyataan SELECT individual tidak menyiratkan apa pun tentang urutan kemunculan baris di hasil akhir karena UNION secara default menghasilkan kumpulan baris yang tidak berurutan. Oleh karena itu, penggunaan ORDER BY dalam konteks ini biasanya terkait dengan LIMIT, sehingga digunakan untuk menentukan subset dari baris yang dipilih untuk diambil untuk SELECT, meskipun itu tidak selalu mempengaruhi urutan baris tersebut di hasil UNION akhir. Jika ORDER BY muncul tanpa LIMIT dalam SELECT, itu dioptimalkan karena itu tidak akan berpengaruh.
Kalimat terakhir ini agak menyesatkan karena seharusnya memiliki efek. Pengoptimalan ini menyebabkan masalah saat Anda berada dalam situasi di mana Anda perlu memesan dalam subkueri.
Untuk memaksa MySQL agar tidak melakukan pengoptimalan ini, Anda dapat menambahkan klausa LIMIT seperti ini:
(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)
Tinggi LIMITberarti Anda dapat menambahkan OFFSETkueri pada keseluruhan jika Anda ingin melakukan sesuatu seperti penomoran halaman.
Ini juga memberi Anda manfaat tambahan karena dapat ORDER BYmenggunakan kolom yang berbeda untuk setiap serikat pekerja.