Saya memikirkan ini beberapa hari yang lalu setelah optimasi SQL. Saya pikir kita bisa sepakat bahwa SQL adalah "bahasa deklaratif" dalam definisi Wikipedia:
Pemrograman paradigma yang mengekspresikan logika perhitungan tanpa menjelaskan aliran kontrolnya
Jika Anda berpikir berapa banyak hal yang dilakukan di balik tirai (melihat statistik, memutuskan apakah indeks berguna, mencari bergabung, bergabung atau hash bergabung, dll. Dll.) Kita harus mengakui bahwa kita hanya memberikan tingkat tinggi logika, dan database menangani semua logika aliran kontrol level rendah.
Juga dalam skenario ini, kadang-kadang pengoptimal database membutuhkan beberapa "petunjuk" dari pengguna untuk memberikan hasil terbaik.
Definisi umum lain dari bahasa "deklaratif" adalah (saya tidak dapat menemukan sumber otoritatif):
Pemrograman paradigma yang mengekspresikan hasil perhitungan yang diinginkan tanpa menjelaskan langkah-langkah untuk mencapainya (juga disingkat dengan "menggambarkan apa, bukan bagaimana")
Jika kami menerima definisi ini, kami menghadapi masalah yang dijelaskan oleh OP.
Masalah pertama adalah bahwa SQL memberi kita beberapa cara yang setara untuk mendefinisikan "hasil yang sama". Mungkin itu adalah kejahatan yang diperlukan: semakin banyak kekuatan ekspresif yang kita berikan pada suatu bahasa, semakin besar kemungkinannya memiliki cara berbeda untuk mengekspresikan hal yang sama.
Sebagai contoh, saya pernah diminta untuk mengoptimalkan kueri ini:
SELECT Distinct CT.cust_type, ct.cust_type_description
from customer c
INNER JOIN
Customer_type CT on c.cust_type=ct.cust_type;
Karena jenisnya jauh lebih sedikit daripada pelanggan dan ada indeks di cust_type
atas meja pelanggan, saya telah mencapai peningkatan besar dengan menulis ulang sebagai:
SELECT CT.cust_type, ct.cust_type_description
from Customer_type CT
Where exists ( select 1 from customer c
Where c.cust_type=ct.cust_type);
Dalam kasus khusus ini, ketika saya bertanya kepada pengembang apa yang ingin dia capai, dia mengatakan kepada saya, "Saya ingin semua jenis pelanggan yang saya miliki setidaknya satu pelanggan", yang kebetulan persis seperti yang dijelaskan oleh kueri pengoptimal.
Jadi, jika saya dapat menemukan kueri yang setara dan lebih efisien, mengapa pengoptimal tidak dapat melakukan hal yang sama?
Tebakan terbaik saya adalah karena dua alasan utama:
SQL mengungkapkan logika:
karena SQL mengekspresikan logika tingkat tinggi, apakah kita benar-benar ingin pengoptimal untuk "mengakali" kita dan logika kita? Saya akan dengan antusias meneriakkan "ya" jika bukan karena berkali-kali saya harus memaksa pengoptimal memilih jalur eksekusi paling efisien. Saya pikir idenya mungkin untuk memungkinkan pengoptimal untuk melakukan yang terbaik (juga merevisi logika kami) tetapi memberi kami "mekanisme petunjuk" untuk datang ke penyelamatan ketika sesuatu menjadi gila (itu akan seperti memiliki roda + rem di sebuah mobil otonom).
Lebih banyak pilihan = lebih banyak waktu
Bahkan pengoptimal RDBMS terbaik tidak menguji SEMUA jalur eksekusi yang mungkin, karena mereka harus sangat cepat: seberapa bagus untuk mengoptimalkan kueri dari 100 ms hingga 10 ms jika saya perlu menghabiskan setiap waktu 100 ms untuk memilih jalur terbaik? Dan itu dengan optimizer yang menghormati "logika tingkat tinggi" kami. Jika juga harus menguji semua kueri SQL yang setara, waktu pengoptimal dapat tumbuh beberapa kali.
Contoh bagus lain dari permintaan menulis ulang yang tidak dapat dilakukan RDBMS adalah (dari posting blog yang menarik ini )
SELECT t1.id, t1.value, SUM(t2.value)
FROM mytable t1
JOIN mytable t2
ON t2.id <= t1.id
GROUP BY t1.id, t1.value;
daripada yang dapat ditulis sebagai ini (Fungsi analitis diperlukan)
SELECT id, value, SUM(t1.value) OVER (ORDER BY id)
FROM mytable
select whatever from sometable where FKValue in (select FKValue from sometable_2 where other_value = :param)
. Itu harus sepele untuk melihat bagaimana menyatakan kembali itu denganexists
ataujoin
.