Saat Anda menggunakan ORDER BY
klausa di dalam sub kueri yang digunakan bersama dengan UNION
mysql akan mengoptimalkan ORDER BY
klausa tersebut.
Ini karena secara default a UNION
mengembalikan daftar tidak berurutan sehingga oleh karena itu an ORDER BY
tidak 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 LIMIT
berarti Anda dapat menambahkan OFFSET
kueri pada keseluruhan jika Anda ingin melakukan sesuatu seperti penomoran halaman.
Ini juga memberi Anda manfaat tambahan karena dapat ORDER BY
menggunakan kolom yang berbeda untuk setiap serikat pekerja.