Namun pada contoh query pertama memiliki kondisi pada kolom a
, sedangkan query kedua memiliki kondisi pada kolom b
. Ini mungkin berasal dari kueri yang sulit dioptimalkan:
SELECT * FROM mytable WHERE a=X OR b=Y
Kueri ini sulit dioptimalkan dengan pengindeksan B-tree sederhana. Apakah mesin mencari indeks pada kolom a
? Atau pada kolom b
? Either way, mencari istilah lain membutuhkan pemindaian tabel.
Oleh karena itu trik menggunakan UNION untuk memisahkan menjadi dua kueri untuk masing-masing satu istilah. Setiap subquery dapat menggunakan indeks terbaik untuk setiap istilah pencarian. Kemudian gabungkan hasilnya menggunakan UNION.
Tetapi kedua himpunan bagian mungkin tumpang tindih, karena beberapa baris di mana b=Y
mungkin juga memiliki a=X
dalam hal ini baris seperti itu terjadi di kedua himpunan bagian. Oleh karena itu Anda harus melakukan eliminasi duplikat, atau melihat beberapa baris dua kali di hasil akhir.
SELECT * FROM mytable WHERE a=X
UNION DISTINCT
SELECT * FROM mytable WHERE b=Y
UNION DISTINCT
mahal karena implementasi tipikal mengurutkan baris untuk menemukan duplikat. Sama seperti jika Anda menggunakan SELECT DISTINCT ...
.
Kami juga memiliki persepsi bahwa itu bahkan lebih "sia-sia" bekerja jika dua subset baris yang Anda gabungkan memiliki banyak baris yang muncul di kedua subset. Banyak baris yang harus dihilangkan.
Tetapi tidak perlu menghilangkan duplikat jika Anda dapat menjamin bahwa dua set baris sudah berbeda. Artinya, jika Anda menjamin tidak ada tumpang tindih. Jika Anda dapat mengandalkan itu, maka tidak ada pilihan lain untuk menghilangkan duplikat, dan oleh karena itu kueri dapat melewati langkah itu, dan karenanya melewatkan penyortiran yang mahal.
Jika Anda mengubah kueri sehingga dijamin memilih subkumpulan baris yang tidak tumpang tindih, itu adalah kemenangan.
SELECT * FROM mytable WHERE a=X
UNION ALL
SELECT * FROM mytable WHERE b=Y AND a!=X
Kedua set ini dijamin tidak akan tumpang tindih. Jika set pertama memiliki baris di mana a=X
dan set kedua memiliki baris di mana a!=X
maka tidak ada baris yang ada di kedua set.
Oleh karena itu, kueri kedua hanya menangkap beberapa dari baris di mana b=Y
, tetapi setiap baris di mana a=X AND b=Y
sudah termasuk dalam set pertama.
Jadi kueri mencapai pencarian yang dioptimalkan untuk dua OR
persyaratan, tanpa menghasilkan duplikat, dan tidak memerlukan UNION DISTINCT
operasi.