Di setiap perusahaan tempat saya bekerja, saya menemukan bahwa orang-orang masih menulis kueri SQL mereka dalam standar ANSI-89:
select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id
daripada standar ANSI-92:
select a.id, b.id, b.address_1
from person a
inner join address b
on a.id = b.id
Untuk kueri yang sangat sederhana seperti ini, tidak ada perbedaan besar dalam keterbacaan, tetapi untuk kueri besar saya menemukan bahwa kriteria bergabung saya dikelompokkan dengan mencantumkan tabel membuatnya lebih mudah untuk melihat di mana saya mungkin memiliki masalah dalam bergabung saya, dan biarkan saya menyimpan semua pemfilteran saya di klausa WHERE saya. Belum lagi saya merasa bahwa gabungan luar jauh lebih intuitif daripada sintaks (+) di Oracle.
Saat saya mencoba menginjili ANSI-92 kepada orang-orang, apakah ada manfaat kinerja konkret dalam menggunakan ANSI-92 dibandingkan ANSI-89? Saya akan mencobanya sendiri, tetapi konfigurasi Oracle yang kami miliki di sini tidak mengizinkan kami menggunakan EXPLAIN PLAN - tidakkah ingin orang mencoba mengoptimalkan kode mereka, bukan?
Jawaban:
Menurut "SQL Performance Tuning" oleh Peter Gulutzan dan Trudy Pelzer, dari enam atau delapan merek RDBMS yang mereka uji, tidak ada perbedaan dalam pengoptimalan atau performa gabungan gaya SQL-89 versus SQL-92. Seseorang dapat berasumsi bahwa sebagian besar mesin RDBMS mengubah sintaks menjadi representasi internal sebelum mengoptimalkan atau menjalankan kueri, sehingga sintaks yang dapat dibaca manusia tidak membuat perbedaan.
Saya juga mencoba menginjili sintaks SQL-92. Enam belas tahun setelah disetujui, inilah saatnya orang mulai menggunakannya! Dan semua merek database SQL sekarang mendukungnya, jadi tidak ada alasan untuk terus menggunakan
(+)
sintaks Oracle atau sintaks*=
Microsoft / Sybase yang tidak standar .Mengenai mengapa sangat sulit untuk menghentikan komunitas pengembang kebiasaan SQL-89, saya hanya dapat berasumsi bahwa ada "dasar piramida" besar pemrogram yang membuat kode dengan salin & tempel, menggunakan contoh kuno dari buku, artikel majalah, atau basis kode lain, dan orang-orang ini tidak mempelajari sintaks baru secara abstrak. Beberapa orang mencocokkan pola, dan beberapa orang belajar dengan menghafal.
Saya secara bertahap melihat orang-orang menggunakan sintaks SQL-92 lebih sering daripada sebelumnya. Saya telah menjawab pertanyaan SQL secara online sejak 1994.
sumber
Standar ANSI092 mencakup beberapa sintaks yang cukup keji. Gabungan alami adalah satu dan Klausul PENGGUNAAN adalah yang lain. IMHO, penambahan kolom ke tabel seharusnya tidak merusak kode tetapi NATURAL JOIN rusak dengan cara yang paling mengerikan. Cara "terbaik" untuk memecahkannya adalah dengan kesalahan kompilasi. Misalnya jika Anda PILIH * di suatu tempat, penambahan kolom bisagagal untuk mengkompilasi. Cara terbaik berikutnya untuk gagal adalah kesalahan waktu proses. Ini lebih buruk karena pengguna Anda mungkin melihatnya, tetapi masih memberi Anda peringatan yang bagus bahwa Anda telah merusak sesuatu. Jika Anda menggunakan ANSI92 dan menulis kueri dengan gabungan NATURAL, itu tidak akan rusak pada waktu kompilasi dan tidak akan rusak pada waktu proses, kueri hanya akan tiba-tiba mulai menghasilkan hasil yang salah. Jenis bug ini berbahaya. Laporan salah, kemungkinan pengungkapan keuangan salah.
Bagi mereka yang tidak terbiasa dengan NATURAL Joins. Mereka menggabungkan dua tabel di setiap nama kolom yang ada di kedua tabel. Yang sangat keren ketika Anda memiliki tombol 4 kolom dan Anda bosan mengetiknya. Masalahnya muncul saat Table1 memiliki kolom yang sudah ada sebelumnya bernama DESCRIPTION dan Anda menambahkan kolom baru ke Table2 bernama, oh saya tidak tahu, sesuatu yang tidak berbahaya seperti, mmm, DESCRIPTION dan sekarang Anda bergabung dengan dua tabel di VARCHAR2 (1000) bidang yang bentuk bebas.
Klausa MENGGUNAKAN dapat menyebabkan ambiguitas total selain masalah yang dijelaskan di atas. Di posting SO lainnya , seseorang menunjukkan ANSI-92 SQL ini dan meminta bantuan untuk membacanya.
Ini sangat ambigu. Saya meletakkan kolom UserID di tabel Perusahaan dan pengguna dan tidak ada keluhan. Bagaimana jika kolom UserID di perusahaan adalah ID dari orang terakhir yang mengubah baris itu?
Saya serius, Adakah yang bisa menjelaskan mengapa ambiguitas seperti itu perlu? Mengapa itu dibangun langsung ke dalam standar?
Saya pikir Bill benar bahwa ada basis besar pengembang yang menyalin / menempelkannya melalui pengkodean. Faktanya, saya dapat mengakui bahwa saya termasuk dalam hal ANSI-92. Setiap contoh yang pernah saya lihat menunjukkan beberapa gabungan yang bersarang dalam tanda kurung. Kejujuran, itu membuat memilih tabel di sql paling sulit. Tapi kemudian seorang evangilis SQL92 menjelaskan bahwa sebenarnya akan memaksa perintah gabungan. YESUS ... semua Copy paster yang pernah saya lihat sekarang benar-benar memaksakan join order - pekerjaan yang 95% waktunya lebih baik diserahkan kepada pengoptimal terutama copy / paster.
Tomalak melakukannya dengan benar ketika dia berkata,
Itu harus memberi saya sesuatu dan saya tidak melihat sisi positifnya. Dan jika ada sisi positifnya, sisi negatifnya adalah elang laut yang terlalu besar untuk diabaikan.
sumber
SELECT *
(kemudian mencari tahu klien bergantung pada pesanan lapangan) - Rasanya agak cerobohBeberapa alasan muncul di benak:
Untuk bagian saya, saya melakukan semua gabungan saya dalam sintaks SQL-92, dan saya mengonversi kode di mana saya bisa. Ini adalah cara yang lebih bersih, lebih mudah dibaca, dan ampuh untuk melakukannya. Tetapi sulit untuk meyakinkan seseorang untuk menggunakan gaya baru, ketika mereka berpikir itu merugikan mereka dalam hal lebih banyak pekerjaan mengetik sementara tidak mengubah hasil kueri.
sumber
Menanggapi postingan NATURAL JOIN and USING di atas.
MENGAPA Anda pernah melihat kebutuhan untuk menggunakan ini - mereka tidak tersedia di ANSI-89 dan ditambahkan untuk ANSI-92 sebagai apa yang saya hanya bisa lihat sebagai jalan pintas.
Saya tidak akan pernah meninggalkan kesempatan bergabung dan akan selalu menentukan tabel / alias dan id.
Bagi saya, satu-satunya cara untuk pergi adalah ANSI-92. Ini lebih bertele-tele dan sintaksnya tidak disukai oleh pengikut ANSI-89 tetapi dengan rapi memisahkan JOINS Anda dari FILTERING Anda.
sumber
Pertama izinkan saya mengatakan bahwa di SQL Server sintaks gabungan luar (* =) tidak memberikan hasil yang benar sepanjang waktu. Ada kalanya ia menafsirkan itu sebagai gabungan silang dan bukan gabungan luar. Jadi, ada alasan bagus untuk berhenti menggunakannya. Dan sintaks gabungan luar itu adalah fitur yang tidak digunakan lagi dan tidak akan ada di versi SQL Server berikutnya setelah SQL Server 2008. Anda masih dapat melakukan gabungan dalam tetapi mengapa ada orang yang mau? Mereka tidak jelas dan jauh lebih sulit untuk dipelihara. Anda tidak dengan mudah mengetahui apa yang merupakan bagian dari join dan apa sebenarnya klausa where.
Salah satu alasan mengapa saya yakin Anda tidak boleh menggunakan sintaks lama adalah memahami join dan apa yang mereka lakukan dan tidak lakukan adalah langkah penting bagi siapa saja yang akan menulis kode SQL. Anda tidak boleh menulis kode SQL apa pun tanpa memahami bergabung secara menyeluruh. Jika Anda memahaminya dengan baik, Anda mungkin akan sampai pada kesimpulan bahwa sintaks ANSI-92 lebih jelas dan lebih mudah dipertahankan. Saya belum pernah bertemu dengan seorang ahli SQL yang tidak menggunakan sintaks ANSI-92 sebagai preferensi dari sintaks lama.
Kebanyakan orang yang pernah saya temui atau hadapi yang menggunakan kode lama, benar-benar tidak memahami join dan dengan demikian mendapat masalah saat menanyakan database. Ini adalah pengalaman pribadi saya jadi saya tidak mengatakan itu selalu benar. Tapi sebagai spesialis data, saya harus memperbaiki terlalu banyak sampah ini selama bertahun-tahun untuk tidak mempercayainya.
sumber
Saya diajari ANSI-89 di sekolah dan bekerja di industri selama beberapa tahun. Kemudian saya meninggalkan dunia DBMS yang menakjubkan selama 8 tahun. Tapi kemudian saya kembali dan hal-hal baru ANSI 92 ini diajarkan. Saya telah mempelajari sintaks Join On dan sekarang saya benar-benar mengajar SQL dan saya merekomendasikan sintaks JOIN ON yang baru.
Tetapi sisi negatifnya yang saya lihat adalah subkueri berkorelasi tampaknya tidak masuk akal mengingat ANSI 92 bergabung. Ketika informasi bergabung dimasukkan di WHERE dan subkueri yang terkait "bergabung" di WHERE semuanya tampak benar dan konsisten. Dalam ANSI 92 tabel bergabung kriteria tidak di MANA dan subquery "bergabung" adalah, sintaks tampaknya tidak konsisten. Di sisi lain, mencoba "memperbaiki" ketidakkonsistenan ini mungkin hanya akan memperburuknya.
sumber
Saya tidak tahu jawabannya secara pasti .. ini adalah perang agama (meskipun derajatnya lebih rendah dari Mac-Pc atau lainnya)
Tebakannya adalah bahwa hingga saat ini, Oracle, (dan mungkin vendor lain juga) tidak mengadopsi standar ANSI-92 (saya pikir itu ada di Oracle v9, atau sekitar itu) dan seterusnya, untuk Pengembang DBA / Db yang bekerja di perusahaan yang masih menggunakan versi ini, (atau ingin kode menjadi portabel di seluruh server yang mungkin menggunakan versi ini, mereka harus tetap menggunakan standar lama ...
Sungguh memalukan, karena sintaks gabungan baru jauh lebih mudah dibaca, dan sintaks lama menghasilkan hasil yang salah (salah) dalam beberapa skenario yang terdokumentasi dengan baik.
sumber
INNER JOIN
pada tahun 1995, meskipunLEFT JOIN
tidak sampai tahun 1996. MySQL telah mendukungnya setidaknya sejak 3.23, dirilis pada tahun 1999; PostgreSQL setidaknya sejak 7.2, dirilis pada tahun 2002. Beberapa Googling biasa tidak memberi saya jawaban untuk Teradata.Inersia dan kepraktisan.
ANSI-92 SQL seperti pengetikan sentuh. Secara teoretis, ini mungkin membuat segalanya lebih baik suatu hari nanti, tetapi sekarang saya dapat mengetik lebih cepat dengan melihat tombol dengan empat jari. Saya harus mundur untuk maju, tanpa jaminan bahwa akan ada imbalan.
Menulis SQL adalah sekitar 10% dari pekerjaan saya. Jika saya memerlukan ANSI-92 SQL untuk memecahkan masalah yang tidak dapat diselesaikan oleh ANSI-89 SQL maka saya akan menggunakannya. (Sebenarnya saya menggunakannya di Access.) Jika menggunakannya sepanjang waktu akan membantu saya menyelesaikan masalah yang ada dengan lebih cepat, saya akan menghabiskan waktu untuk mengasimilasinya. Tapi saya bisa mengeluarkan ANSI-89 SQL tanpa pernah memikirkan sintaksnya. Saya dibayar untuk menyelesaikan masalah - memikirkan tentang sintaks SQL hanya membuang-buang waktu dan uang majikan saya.
Suatu hari nanti, Belalang muda, Anda akan mempertahankan penggunaan sintaks SQL ANSI-92 Anda dari orang-orang muda yang mengeluh bahwa Anda harus menggunakan SQL3 (atau apa pun). Dan kemudian Anda akan mengerti. :-)
sumber
Saya memiliki kueri yang awalnya ditulis untuk SQL Server 6.5, yang tidak mendukung sintaks bergabung SQL 92, yaitu
malah ditulis sebagai
Kueri telah ada selama beberapa waktu, dan data yang relevan telah terkumpul untuk membuat kueri berjalan terlalu lambat, hanya 90 detik untuk diselesaikan. Pada saat masalah ini muncul, kami telah meningkatkan ke SQL Server 7.
Setelah menyia-nyiakan indeks dan easter-egging lainnya, saya mengubah sintaks bergabung menjadi SQL 92 compliant. Waktu kueri turun menjadi 3 detik.
Ada alasan bagus untuk beralih.
Diposting ulang dari sini .
sumber
Saya dapat menjawab dari sudut pandang rata-rata pengembang, mengetahui cukup SQL untuk memahami kedua sintaksis, tetapi masih googling sintaks yang tepat setiap kali saya membutuhkannya ... :-P (Saya tidak melakukan SQL sepanjang hari , hanya memperbaiki beberapa masalah dari waktu ke waktu.)
Sebenarnya, menurut saya bentuk pertama lebih intuitif, tidak membuat hierarki yang jelas antara kedua tabel. Fakta bahwa saya belajar SQL dengan kemungkinan buku-buku lama, menunjukkan bentuk pertama, mungkin tidak membantu ... ;-)
Dan referensi pertama yang saya temukan pada pencarian sql di Google (yang mengembalikan sebagian besar jawaban Prancis untuk saya ... ) pertama menunjukkan formulir yang lebih tua (lalu jelaskan yang kedua).
Hanya memberikan beberapa petunjuk tentang pertanyaan "mengapa" ... ^ _ ^ Saya harus membaca sebuah buku modern yang bagus (DB agnostik) tentang topik tersebut. Jika seseorang memiliki saran ...
sumber
Saya tidak dapat berbicara untuk semua sekolah tetapi di universitas saya ketika kami melakukan modul SQL di kursus kami, mereka tidak mengajar ANSI-92, mereka mengajar ANSI-89 - pada sistem VAX lama saat itu! Saya tidak terpapar ANSI-92 sampai saya mulai menggali di Access setelah membuat beberapa kueri menggunakan desainer kueri dan kemudian menggali ke dalam kode SQL. Menyadari saya tidak tahu bagaimana itu menyelesaikan gabungan, atau implikasi dari sintaks saya mulai menggali lebih dalam sehingga saya bisa memahaminya.
Mengingat bahwa dokumentasi yang tersedia tidak terlalu intuitif dalam banyak kasus, dan bahwa orang cenderung berpegang pada apa yang mereka ketahui dan dalam banyak kasus tidak berusaha untuk belajar lebih dari yang mereka butuhkan untuk menyelesaikan pekerjaan mereka, itu mudah untuk melihat mengapa adopsi memakan waktu begitu lama.
Tentu saja, ada penginjil teknis yang suka mengutak-atik dan memahami dan cenderung menjadi tipe yang mengadopsi prinsip-prinsip "lebih baru" dan mencoba mengubah yang lainnya.
Anehnya, menurut saya banyak programmer yang keluar dari sekolah dan berhenti maju; berpikir bahwa karena inilah yang diajarkan kepada mereka, inilah cara melakukannya. Baru setelah Anda melepaskan penutup mata, Anda menyadari bahwa sekolah hanya dimaksudkan untuk mengajari Anda dasar-dasarnya dan memberi Anda pemahaman yang cukup untuk mempelajari sisanya sendiri dan bahwa Anda benar-benar hampir tidak menyentuh permukaan dari apa yang perlu diketahui; sekarang tugas Anda untuk melanjutkan jalan itu.
Tentu saja, itu hanya pendapat saya berdasarkan pengalaman saya.
sumber
1) Cara standar untuk menulis OUTER JOIN, versus * = atau (+) =
2) GABUNG ALAMI
3) Bergantung pada mesin database, tren ANSI-92 menjadi lebih optimal.
4) Pengoptimalan manual:
Katakanlah kita memiliki sintaks berikutnya (ANSI-89):
Itu bisa ditulis sebagai:
Tetapi juga sebagai:
Semuanya (1), (2), (3) mengembalikan hasil yang sama, namun dioptimalkan secara berbeda, bergantung pada mesin database tetapi kebanyakan dari mereka melakukan:
5) Pertanyaan yang lebih lama tidak terlalu berantakan.
sumber
Alasan orang menggunakan ANSI-89 dari pengalaman praktis saya dengan programmer dan trainee tua dan muda serta fresh graduate:
Saya pribadi lebih suka ANSI-92 dan mengubah setiap kueri yang saya lihat dalam sintaks ANSI-89 terkadang hanya untuk lebih memahami Pernyataan SQL yang ada. Tetapi saya menyadari bahwa mayoritas orang yang bekerja dengan saya tidak cukup terampil untuk menulis gabungan di banyak tabel. Mereka membuat kode sebaik mungkin dan menggunakan apa yang mereka hafal saat pertama kali menemukan pernyataan SQL.
sumber
Berikut adalah beberapa poin yang membandingkan SQL-89, dan SQL-92 dan menghapus beberapa kesalahpahaman di jawaban lain.
NATURAL JOINS
adalah ide yang buruk. Mereka implisit dan membutuhkan informasi meta tentang tabel. Tidak ada tentang SQL-92 yang memerlukan penggunaannya jadi abaikan saja . Mereka tidak relevan dengan diskusi ini.USING
adalah ide yang bagus, ini memiliki dua efek:id
di kedua tabel. Setelah Anda menggabungkan tabel, ini menjadi ambigu dan membutuhkan aliasing eksplisit. Lebih lanjut, paraid
s yang bergabung hampir pasti memiliki data yang berbeda. Jika Anda menggabungkan orang ke perusahaan, Anda sekarang harus membuat alias satuid
keperson_id
, dan satuid
kecompany_id
, tanpanya penggabungan akan menghasilkan dua kolom yang ambigu. Menggunakan pengenal unik global untuk kunci pengganti tabel adalah konvensi yang digunakan oleh reward standarUSING
.CROSS JOIN
. ACROSS JOIN
tidak mengurangi set, ia secara implisit menumbuhkannya.FROM T1,T2
sama denganFROM T1 CROSS JOIN T2
, yang menghasilkan gabungan Cartesian yang biasanya bukan yang Anda inginkan. Memiliki selektivitas untuk mengurangi itu dihapus keWHERE
kondisional jauh berarti Anda lebih cenderung membuat kesalahan selama desain.,
dan SQL-92 eksplisitJOIN
memiliki prioritas yang berbeda.JOIN
memiliki prioritas yang lebih tinggi. Lebih buruk lagi, beberapa database seperti MySQL melakukan kesalahan ini untuk waktu yang sangat lama. . Jadi mencampur dua gaya adalah ide yang buruk, dan gaya yang jauh lebih populer saat ini adalah gaya SQL-92.sumber
Oracle sama sekali tidak mengimplementasikan ANSI-92. Saya mengalami beberapa masalah, paling tidak karena tabel data di Aplikasi Oracle diberkahi dengan sangat baik dengan kolom. Jika jumlah kolom di gabungan Anda melebihi sekitar 1050 kolom (yang sangat mudah dilakukan di Apps), maka Anda akan mendapatkan kesalahan palsu ini yang sama sekali tidak masuk akal:
Menulis ulang kueri untuk menggunakan sintaks gabungan gaya lama membuat masalah hilang, yang tampaknya menunjukkan kesalahan tepat pada penerapan gabungan ANSI-92.
Sampai saya menemui masalah ini, saya adalah promotor ASNI-92 yang setia, karena keuntungannya dalam mengurangi kemungkinan cross join yang tidak disengaja, yang terlalu mudah dilakukan dengan sintaks gaya lama.
Sekarang, bagaimanapun, saya merasa jauh lebih sulit untuk memaksakannya. Mereka menunjuk pada implementasi Oracle yang buruk dan berkata, "Kami akan melakukannya dengan cara kami, terima kasih."
sumber
Standar SQL baru mewarisi segalanya dari standar sebelumnya, alias 'belenggu kompatibilitas'. Jadi gaya gabungan 'lama' / 'dipisahkan koma' / 'tidak memenuhi syarat' adalah sytax SQL-92 yang benar-benar valid.
Sekarang, saya berpendapat bahwa SQL-92
NATURAL JOIN
adalah satu-satunya gabungan yang Anda butuhkan. Sebagai contoh, saya berpendapat ini lebih unggulinner join
karena tidak menghasilkan kolom duplikat - tidak ada lagi variabel rentang dalamSELECT
klausa untuk membedakan kolom! Tetapi saya tidak dapat berharap untuk mengubah setiap hati dan pikiran, jadi saya perlu bekerja dengan pembuat kode yang akan terus mengadopsi apa yang secara pribadi saya anggap sebagai gaya gabungan warisan (dan mereka bahkan mungkin menyebut variabel rentang sebagai 'alias'!). Ini adalah sifat kerja tim dan tidak beroperasi dalam ruang hampa.Salah satu kritik dari bahasa SQL adalah bahwa hasil yang sama dapat diperoleh menggunakan sejumlah sintaks yang setara secara semantik (beberapa menggunakan aljabar relasional, beberapa menggunakan kalkulus relasional), di mana memilih yang 'terbaik' hanya bergantung pada gaya pribadi . Jadi saya merasa nyaman dengan 'gaya lama' bergabung seperti saya
INNER
. Apakah saya akan meluangkan waktu untuk menulis ulangNATURAL
tergantung pada konteksnya.sumber