Apa kesalahan pengembangan database umum yang dilakukan oleh pengembang aplikasi?
Apa kesalahan pengembangan database umum yang dilakukan oleh pengembang aplikasi?
Jawaban:
1. Tidak menggunakan indeks yang sesuai
Ini relatif mudah tetapi tetap saja terjadi setiap saat. Kunci asing harus memiliki indeks pada mereka. Jika Anda menggunakan bidang dalam WHERE
Anda harus (mungkin) memiliki indeks di dalamnya. Indeks semacam itu harus sering mencakup beberapa kolom berdasarkan kueri yang perlu Anda jalankan.
2. Tidak menegakkan integritas referensial
Basis data Anda mungkin berbeda di sini, tetapi jika basis data Anda mendukung integritas referensial - artinya semua kunci asing dijamin untuk menunjuk ke entitas yang ada - Anda harus menggunakannya.
Sangat umum untuk melihat kegagalan ini pada database MySQL. Saya tidak percaya MyISAM mendukungnya. InnoDB tidak. Anda akan menemukan orang-orang yang menggunakan MyISAM atau mereka yang menggunakan InnoDB tetapi tidak menggunakannya.
Lebih banyak di sini:
3. Menggunakan kunci primer alami daripada pengganti (teknis)
Kunci alami adalah kunci berdasarkan data yang bermakna secara eksternal yang (seolah-olah) unik. Contoh umum adalah kode produk, kode negara dua huruf (AS), nomor jaminan sosial dan sebagainya. Kunci pengganti atau teknis adalah yang sama sekali tidak memiliki makna di luar sistem. Mereka diciptakan murni untuk mengidentifikasi entitas dan biasanya bidang penambahan otomatis (SQL Server, MySQL, lainnya) atau urutan (terutama Oracle).
Menurut pendapat saya, Anda harus selalu menggunakan kunci pengganti. Masalah ini muncul dalam pertanyaan-pertanyaan ini:
Ini adalah topik yang agak kontroversial di mana Anda tidak akan mendapatkan persetujuan universal. Meskipun Anda mungkin menemukan beberapa orang, yang berpikir kunci alami dalam beberapa situasi OK, Anda tidak akan menemukan kritik terhadap kunci pengganti selain tidak perlu diperdebatkan. Kelemahan yang cukup kecil jika Anda bertanya kepada saya.
Ingat, bahkan negara dapat tidak ada lagi (misalnya, Yugoslavia).
4. Menulis pertanyaan yang mengharuskan DISTINCT
untuk bekerja
Anda sering melihat ini dalam kueri yang dihasilkan ORM. Lihat output log dari Hibernate dan Anda akan melihat semua pertanyaan dimulai dengan:
SELECT DISTINCT ...
Ini adalah sedikit jalan pintas untuk memastikan Anda tidak mengembalikan baris duplikat dan karenanya mendapatkan objek duplikat. Terkadang Anda akan melihat orang melakukan hal ini juga. Jika Anda melihatnya terlalu banyak itu adalah bendera merah nyata. Tidak DISTINCT
buruk atau tidak memiliki aplikasi yang valid. Memang (pada kedua hitungan) tapi itu bukan pengganti atau penghenti sementara untuk menulis pertanyaan yang benar.
Dari Why I Bate DISTINCT :
Di mana segala sesuatunya mulai memburuk menurut pendapat saya adalah ketika pengembang membangun kueri yang substansial, bergabung dengan tabel bersama, dan tiba-tiba ia menyadari bahwa sepertinya ia mendapatkan duplikat (atau bahkan lebih) baris dan respons langsungnya ... "solusi" untuk "masalah" ini adalah membuang kata kunci DISTINCT dan POOF semua masalahnya hilang.
5. Mendukung agregasi daripada bergabung
Kesalahan umum lainnya oleh pengembang aplikasi database adalah tidak menyadari betapa lebih mahal agregasi (yaitu GROUP BY
klausa) dapat dibandingkan dengan bergabung.
Untuk memberi Anda gambaran betapa meluasnya ini, saya telah menulis tentang topik ini beberapa kali di sini dan banyak downvoted untuk itu. Sebagai contoh:
Dari pernyataan SQL - "join" vs "group by and having" :
Kueri pertama:
SELECT userid FROM userrole WHERE roleid IN (1, 2, 3) GROUP by userid HAVING COUNT(1) = 3
Waktu permintaan: 0,312 s
Kueri kedua:
SELECT t1.userid FROM userrole t1 JOIN userrole t2 ON t1.userid = t2.userid AND t2.roleid = 2 JOIN userrole t3 ON t2.userid = t3.userid AND t3.roleid = 3 AND t1.roleid = 1
Waktu permintaan: 0,016 dtk
Betul. Versi gabungan yang saya usulkan dua puluh kali lebih cepat dari versi agregat.
6. Tidak menyederhanakan pertanyaan kompleks melalui tampilan
Tidak semua vendor database mendukung tampilan tetapi bagi mereka yang melakukannya, mereka dapat sangat menyederhanakan pertanyaan jika digunakan dengan bijaksana. Misalnya, pada satu proyek saya menggunakan model Partai generik untuk CRM. Ini adalah teknik pemodelan yang sangat kuat dan fleksibel tetapi dapat menyebabkan banyak bergabung. Dalam model ini ada:
Contoh:
Jadi ada lima meja yang bergabung untuk menghubungkan Ted dengan majikannya. Anda menganggap semua karyawan adalah Orang (bukan organisasi) dan memberikan pandangan penolong ini:
CREATE VIEW vw_employee AS
SELECT p.title, p.given_names, p.surname, p.date_of_birth, p2.party_name employer_name
FROM person p
JOIN party py ON py.id = p.id
JOIN party_role child ON p.id = child.party_id
JOIN party_role_relationship prr ON child.id = prr.child_id AND prr.type = 'EMPLOYMENT'
JOIN party_role parent ON parent.id = prr.parent_id = parent.id
JOIN party p2 ON parent.party_id = p2.id
Dan tiba-tiba Anda memiliki pandangan yang sangat sederhana tentang data yang Anda inginkan tetapi pada model data yang sangat fleksibel.
7. Tidak membersihkan input
Ini sangat besar. Sekarang saya suka PHP tetapi jika Anda tidak tahu apa yang Anda lakukan, sangat mudah membuat situs yang rentan diserang. Tidak ada yang lebih baik dari kisah Bobby Tables yang kecil .
Data yang disediakan oleh pengguna melalui URL, data formulir, dan cookie harus selalu dianggap sebagai permusuhan dan disanitasi. Pastikan Anda mendapatkan apa yang Anda harapkan.
8. Tidak menggunakan pernyataan yang disiapkan
Pernyataan yang disiapkan adalah saat Anda mengkompilasi kueri dikurangi data yang digunakan dalam sisipan, pembaruan, dan WHERE
klausa dan kemudian menyediakannya nanti. Sebagai contoh:
SELECT * FROM users WHERE username = 'bob'
vs.
SELECT * FROM users WHERE username = ?
atau
SELECT * FROM users WHERE username = :username
tergantung pada platform Anda.
Saya telah melihat database berlutut dengan melakukan ini. Pada dasarnya, setiap kali basis data modern menemukan kueri baru yang harus dikompilasinya. Jika memenuhi kueri yang terlihat sebelumnya, Anda memberi database kesempatan untuk men-cache permintaan yang dikompilasi dan rencana eksekusi. Dengan melakukan kueri banyak, Anda memberi kesempatan pada database untuk mencari tahu dan mengoptimalkannya (misalnya, dengan menyematkan kueri yang dikompilasi dalam memori).
Menggunakan pernyataan yang disiapkan juga akan memberi Anda statistik yang bermakna tentang seberapa sering kueri tertentu digunakan.
Pernyataan yang disiapkan juga akan lebih melindungi Anda terhadap serangan injeksi SQL.
9. Tidak cukup normal
Normalisasi basis data pada dasarnya adalah proses mengoptimalkan desain basis data atau cara Anda mengatur data ke dalam tabel.
Baru minggu ini saya menemukan beberapa kode di mana seseorang telah meledakkan array dan memasukkannya ke dalam satu bidang dalam database. Normalisasi itu akan memperlakukan elemen array itu sebagai baris terpisah dalam tabel anak (yaitu hubungan satu-ke-banyak).
Ini juga muncul dalam metode Terbaik untuk menyimpan daftar ID pengguna :
Saya telah melihat di sistem lain bahwa daftar ini disimpan dalam array PHP serial.
Tetapi kurangnya normalisasi muncul dalam banyak bentuk.
Lebih:
10. Normalisasi terlalu banyak
Ini mungkin tampak seperti kontradiksi dengan poin sebelumnya tetapi normalisasi, seperti banyak hal, adalah alat. Ini adalah sarana untuk mencapai tujuan dan bukan tujuan untuk mencapai tujuan itu sendiri. Saya pikir banyak pengembang melupakan ini dan mulai memperlakukan "cara" sebagai "akhir". Pengujian unit adalah contoh utama dari ini.
Saya pernah bekerja pada suatu sistem yang memiliki hierarki besar untuk klien yang berjalan seperti:
Licensee -> Dealer Group -> Company -> Practice -> ...
sehingga Anda harus bergabung sekitar 11 tabel bersama sebelum Anda bisa mendapatkan data yang berarti. Itu adalah contoh bagus dari normalisasi yang diambil terlalu jauh.
Lebih penting lagi, denasionalisasi yang hati-hati dan dipertimbangkan dapat memiliki manfaat kinerja yang besar tetapi Anda harus benar-benar berhati-hati ketika melakukan ini.
Lebih:
11. Menggunakan busur eksklusif
Busur eksklusif adalah kesalahan umum di mana sebuah tabel dibuat dengan dua atau lebih kunci asing di mana satu dan hanya satu saja yang bisa non-nol. Kesalahan besar. Untuk satu hal, mempertahankan integritas data menjadi jauh lebih sulit. Setelah semua, bahkan dengan integritas referensial, tidak ada yang mencegah dua atau lebih kunci asing ini ditetapkan (terlepas dari kendala pemeriksaan kompleks).
Dari Panduan Praktis ke Desain Basis Data Relasional :
Kami telah sangat menyarankan terhadap konstruksi busur eksklusif sedapat mungkin, untuk alasan yang baik bahwa mereka bisa canggung untuk menulis kode dan menimbulkan lebih banyak kesulitan pemeliharaan.
12. Tidak melakukan analisis kinerja pada permintaan sama sekali
Pragmatisme berkuasa, terutama di dunia basis data. Jika Anda berpegang teguh pada prinsip-prinsip sampai-sampai mereka telah menjadi dogma maka kemungkinan besar Anda telah melakukan kesalahan. Ambil contoh kueri agregat dari atas. Versi agregat mungkin terlihat "bagus" tetapi kinerjanya menyedihkan. Perbandingan kinerja seharusnya mengakhiri perdebatan (tetapi tidak) tetapi lebih pada intinya: menyemburkan pandangan yang kurang informasi seperti itu pada awalnya adalah bodoh, bahkan berbahaya.
13. Ketergantungan berlebihan pada UNION ALL dan khususnya konstruksi UNION
UNION dalam istilah SQL hanya menggabungkan set data kongruen, yang berarti mereka memiliki jenis dan jumlah kolom yang sama. Perbedaan di antara mereka adalah bahwa UNION ALL adalah gabungan sederhana dan harus disukai sedapat mungkin sedangkan UNION secara implisit akan melakukan DISTINCT untuk menghapus duplikat tupel.
UNION, seperti DISTINCT, mendapatkan tempatnya. Ada aplikasi yang valid. Tetapi jika Anda menemukan diri Anda melakukan banyak hal, terutama di subqueries, maka Anda mungkin melakukan sesuatu yang salah. Itu mungkin kasus konstruksi kueri yang buruk atau model data yang dirancang dengan buruk yang memaksa Anda untuk melakukan hal-hal seperti itu.
UNION, khususnya ketika digunakan dalam gabungan atau subqueries dependen, dapat melumpuhkan database. Cobalah untuk menghindarinya sedapat mungkin.
14. Menggunakan kondisi ATAU dalam kueri
Ini mungkin tampak tidak berbahaya. Bagaimanapun, AND tidak masalah. ATAU seharusnya OK juga? Salah. Pada dasarnya kondisi DAN membatasi kumpulan data sedangkan kondisi ATAU menumbuhkannya tetapi tidak dengan cara yang cocok untuk optimasi. Terutama ketika kondisi ATAU yang berbeda mungkin berpotongan sehingga memaksa pengoptimal untuk secara efektif ke operasi yang berbeda pada hasilnya.
Buruk:
... WHERE a = 2 OR a = 5 OR a = 11
Lebih baik:
... WHERE a IN (2, 5, 11)
Sekarang pengoptimal SQL Anda dapat secara efektif mengubah kueri pertama menjadi kueri kedua. Tapi mungkin tidak. Tapi jangan lakukan itu.
15. Tidak merancang model data mereka untuk memberikan solusi berkinerja tinggi
Ini adalah titik sulit untuk diukur. Ini biasanya diamati oleh efeknya. Jika Anda menemukan diri Anda menulis kueri degil untuk tugas-tugas yang relatif sederhana atau bahwa permintaan untuk mengetahui informasi yang relatif mudah tidak efisien, maka Anda mungkin memiliki model data yang buruk.
Dalam beberapa hal, poin ini merangkum semua yang sebelumnya tetapi lebih merupakan kisah peringatan bahwa melakukan hal-hal seperti optimasi kueri sering dilakukan pertama kali ketika harus dilakukan kedua. Pertama dan terutama Anda harus memastikan Anda memiliki model data yang baik sebelum mencoba mengoptimalkan kinerja. Seperti yang Knuth katakan:
Optimalisasi prematur adalah akar dari semua kejahatan
16. Penggunaan Transaksi Database yang salah
Semua perubahan data untuk proses tertentu harus bersifat atom. Yaitu Jika operasi berhasil, ia melakukannya sepenuhnya. Jika gagal, data tidak berubah. - Seharusnya tidak ada kemungkinan perubahan 'setengah jadi'.
Idealnya, cara paling sederhana untuk mencapai ini adalah bahwa seluruh desain sistem harus berusaha untuk mendukung semua perubahan data melalui pernyataan INSERT / UPDATE / DELETE tunggal. Dalam hal ini, tidak diperlukan penanganan transaksi khusus, karena mesin database Anda harus melakukannya secara otomatis.
Namun, jika ada proses yang membutuhkan beberapa pernyataan dilakukan sebagai unit untuk menjaga data dalam keadaan yang konsisten, maka Kontrol Transaksi yang tepat diperlukan.
Juga disarankan untuk memperhatikan subtelties tentang bagaimana lapisan konektivitas basis data Anda, dan mesin basis data berinteraksi dalam hal ini.
17. Tidak memahami paradigma 'set-based'
Bahasa SQL mengikuti paradigma spesifik yang cocok untuk jenis masalah tertentu. Meskipun demikian, berbagai ekstensi khusus vendor, bahasa tersebut berjuang untuk menangani masalah yang sepele dalam bahasa seperti Java, C #, Delphi dll.
Kurangnya pemahaman ini memanifestasikan dirinya dalam beberapa cara.
Tentukan pembagian tanggung jawab yang jelas, dan berusaha untuk menggunakan alat yang tepat untuk menyelesaikan setiap masalah.
Desain database utama dan kesalahan pemrograman yang dibuat oleh pengembang
Desain dan penggunaan basis data egois. Pengembang sering memperlakukan database sebagai objek penyimpanan pribadi mereka tanpa mempertimbangkan kebutuhan pemangku kepentingan lain dalam data. Ini juga berlaku untuk arsitek aplikasi. Desain basis data yang buruk dan integritas data menyulitkan pihak ketiga yang bekerja dengan data dan secara substansial dapat meningkatkan biaya siklus hidup sistem. Pelaporan dan SIM cenderung menjadi sepupu yang buruk dalam desain aplikasi dan hanya dilakukan sebagai renungan.
Menyalahgunakan data yang dinormalisasi. Melebih-lebihkan data yang dinormalisasi dan berusaha mempertahankannya di dalam aplikasi adalah resep untuk masalah integritas data. Gunakan denormalisasi dengan hemat. Tidak ingin menambahkan gabungan ke kueri bukan alasan untuk menormalisasi.
Takut menulis SQL. SQL bukanlah ilmu roket dan sebenarnya cukup baik dalam melakukan tugasnya. Lapisan pemetaan O / R cukup baik dalam melakukan 95% dari pertanyaan yang sederhana dan cocok dengan model itu. Terkadang SQL adalah cara terbaik untuk melakukan pekerjaan itu.
Kebijakan Dogmatic 'No Stored Procedures'. Terlepas dari apakah Anda percaya prosedur tersimpan itu jahat, sikap dogmatis semacam ini tidak ada dalam proyek perangkat lunak.
Tidak mengerti desain database. Normalisasi adalah teman Anda dan itu bukan ilmu roket. Bergabung dan kardinalitas adalah konsep yang cukup sederhana - jika Anda terlibat dalam pengembangan aplikasi database benar-benar tidak ada alasan untuk tidak memahaminya.
Penggunaan berlebihan dan / atau ketergantungan pada prosedur tersimpan.
Beberapa pengembang aplikasi melihat prosedur tersimpan sebagai perpanjangan langsung kode tingkat tengah / depan. Ini tampaknya menjadi sifat umum dalam pengembang tumpukan Microsoft, (saya salah, tapi saya sudah tumbuh dari itu) dan menghasilkan banyak prosedur tersimpan yang melakukan logika bisnis yang kompleks dan pemrosesan alur kerja. Ini jauh lebih baik dilakukan di tempat lain.
Prosedur tersimpan berguna di mana sebenarnya telah terbukti bahwa beberapa faktor teknis nyata mengharuskan penggunaannya (misalnya, kinerja dan keamanan) Misalnya, menjaga agregasi / penyaringan kumpulan data besar "dekat dengan data".
Saya baru-baru ini harus membantu memelihara dan meningkatkan aplikasi desktop Delphi besar yang 70% dari logika bisnis dan aturan diimplementasikan dalam 1400 prosedur tersimpan SQL Server (sisanya di event handler UI). Ini adalah mimpi buruk, terutama karena sulitnya memperkenalkan pengujian unit yang efektif untuk TSQL, kurangnya enkapsulasi dan alat yang buruk (Debuggers, editor).
Bekerja dengan tim Java di masa lalu saya dengan cepat menemukan bahwa sering kali kebalikan total terjadi di lingkungan itu. Seorang Arsitek Java pernah mengatakan kepada saya: "Basis data adalah untuk data, bukan kode."
Hari ini saya pikir itu kesalahan untuk tidak mempertimbangkan procs yang disimpan sama sekali, tetapi mereka harus digunakan hemat (tidak secara default) dalam situasi di mana mereka memberikan manfaat yang bermanfaat (lihat jawaban lain).
Masalah nomor satu? Mereka hanya menguji pada database mainan. Jadi mereka tidak tahu bahwa SQL mereka akan merangkak ketika database menjadi besar, dan seseorang harus datang dan memperbaikinya nanti (suara yang bisa Anda dengar adalah gigiku menggigil).
Tidak menggunakan indeks.
Kinerja Buruk Disebabkan oleh Subqueries yang Berhubungan
Sebagian besar waktu Anda ingin menghindari subquery yang berhubungan. Subquery berkorelasi jika, dalam subquery, ada referensi ke kolom dari kueri luar. Ketika ini terjadi, subquery dieksekusi setidaknya sekali untuk setiap baris yang dikembalikan dan bisa dieksekusi lebih banyak jika kondisi lain diterapkan setelah kondisi yang mengandung subquery berkorelasi diterapkan.
Maafkan contoh yang dibuat dan sintaksis Oracle, tetapi katakanlah Anda ingin menemukan semua karyawan yang telah dipekerjakan di salah satu toko Anda sejak terakhir kali toko melakukan kurang dari $ 10.000 penjualan dalam sehari.
select e.first_name, e.last_name
from employee e
where e.start_date >
(select max(ds.transaction_date)
from daily_sales ds
where ds.store_id = e.store_id and
ds.total < 10000)
Subquery dalam contoh ini berkorelasi dengan permintaan luar oleh store_id dan akan dieksekusi untuk setiap karyawan di sistem Anda. Salah satu cara query ini dapat dioptimalkan adalah dengan memindahkan subquery ke tampilan inline.
select e.first_name, e.last_name
from employee e,
(select ds.store_id,
max(s.transaction_date) transaction_date
from daily_sales ds
where ds.total < 10000
group by s.store_id) dsx
where e.store_id = dsx.store_id and
e.start_date > dsx.transaction_date
Dalam contoh ini, kueri dalam dari klausa sekarang menjadi inline-view (lagi beberapa sintaks khusus Oracle) dan hanya dijalankan sekali. Bergantung pada model data Anda, kueri ini mungkin akan mengeksekusi lebih cepat. Ini akan berkinerja lebih baik daripada permintaan pertama karena jumlah karyawan bertambah. Kueri pertama benar-benar dapat berkinerja lebih baik jika ada beberapa karyawan dan banyak toko (dan mungkin banyak toko tidak memiliki karyawan) dan tabel daily_sales diindeks di store_id. Ini bukan skenario yang mungkin tetapi menunjukkan bagaimana kueri yang berkorelasi dapat berkinerja lebih baik daripada alternatif.
Saya telah melihat pengembang junior mengkorelasikan subkueri berkali-kali dan biasanya berdampak besar pada kinerja. Namun, ketika menghapus subquery yang berkorelasi pastikan untuk melihat rencana menjelaskan sebelum dan sesudah untuk memastikan Anda tidak membuat kinerja lebih buruk.
Menggunakan Access alih-alih database "nyata". Ada banyak basis data kecil dan bahkan gratis seperti SQL Express , MySQL , dan SQLite yang akan bekerja dan berskala jauh lebih baik. Aplikasi sering perlu mengukur dengan cara yang tidak terduga.
Menggunakan Excel untuk menyimpan (jumlah besar) data.
Saya telah melihat perusahaan memegang ribuan baris dan menggunakan beberapa lembar kerja (karena batas baris 65.535 pada versi Excel sebelumnya).
Excel sangat cocok untuk laporan, penyajian data, dan tugas lainnya, tetapi tidak boleh diperlakukan sebagai basis data.
Saya ingin menambahkan: Mendukung kode "Elegan" daripada kode berkinerja tinggi. Kode yang bekerja paling baik terhadap basis data seringkali jelek bagi mata pengembang aplikasi.
Percaya omong kosong tentang optimasi prematur. Database harus mempertimbangkan kinerja dalam desain asli dan dalam pengembangan selanjutnya. Kinerja adalah 50% dari desain basis data (40% adalah integritas data dan 10% terakhir adalah keamanan) menurut saya. Basis data yang tidak dibangun dari bawah ke atas untuk melakukan akan berkinerja buruk begitu pengguna nyata dan lalu lintas nyata ditempatkan terhadap database. Optimalisasi prematur tidak berarti tidak ada optimasi! Itu tidak berarti Anda harus menulis kode yang hampir selalu berkinerja buruk karena Anda merasa lebih mudah (kursor misalnya yang tidak boleh diizinkan dalam database produksi kecuali semua yang lain gagal). Ini berarti Anda tidak perlu melihat sedikit kinerja terakhir sampai Anda perlu. Banyak yang diketahui tentang apa yang akan berkinerja lebih baik pada basis data,
Tidak menggunakan kueri parameterisasi. Mereka sangat berguna dalam menghentikan SQL Injection .
Ini adalah contoh spesifik untuk tidak membersihkan data input, yang disebutkan dalam jawaban lain.
Aku benci ketika pengembang menggunakan pernyataan pilih bersarang atau bahkan berfungsi mengembalikan hasil pernyataan pilih di dalam bagian "SELECT" dari permintaan.
Saya benar-benar terkejut saya tidak melihat ini di tempat lain di sini, mungkin saya mengabaikannya, meskipun @adam memiliki masalah yang sama.
Contoh:
SELECT
(SELECT TOP 1 SomeValue FROM SomeTable WHERE SomeDate = c.Date ORDER BY SomeValue desc) As FirstVal
,(SELECT OtherValue FROM SomeOtherTable WHERE SomeOtherCriteria = c.Criteria) As SecondVal
FROM
MyTable c
Dalam skenario ini, jika MyTable mengembalikan 10.000 baris hasilnya adalah seolah-olah kueri hanya menjalankan 20001 kueri, karena harus menjalankan kueri awal ditambah kueri masing-masing tabel lainnya satu kali untuk setiap baris hasil.
Pengembang dapat pergi dengan ini bekerja dalam lingkungan pengembangan di mana mereka hanya mengembalikan beberapa baris data dan sub tabel biasanya hanya memiliki sejumlah kecil data, tetapi dalam lingkungan produksi, permintaan semacam ini dapat menjadi mahal secara eksponensial karena lebih data ditambahkan ke tabel.
Contoh yang lebih baik (belum tentu sempurna) akan menjadi seperti:
SELECT
s.SomeValue As FirstVal
,o.OtherValue As SecondVal
FROM
MyTable c
LEFT JOIN (
SELECT SomeDate, MAX(SomeValue) as SomeValue
FROM SomeTable
GROUP BY SomeDate
) s ON c.Date = s.SomeDate
LEFT JOIN SomeOtherTable o ON c.Criteria = o.SomeOtherCriteria
Ini memungkinkan pengoptimal basis data untuk mengocok data bersama, daripada meminta kembali pada setiap catatan dari tabel utama dan saya biasanya menemukan ketika saya harus memperbaiki kode di mana masalah ini telah dibuat, saya biasanya akhirnya meningkatkan kecepatan permintaan sebesar 100% atau lebih banyak sekaligus mengurangi penggunaan CPU dan memori.
Untuk database berbasis SQL:
Tidak mengambil cadangan sebelum memperbaiki beberapa masalah di dalam basis data produksi.
Menggunakan perintah DDL pada objek yang disimpan (seperti tabel, tampilan) dalam prosedur tersimpan.
Takut menggunakan proc tersimpan atau takut menggunakan kueri ORM di mana pun lebih efisien / tepat untuk digunakan.
Mengabaikan penggunaan profiler basis data, yang dapat memberi tahu Anda secara persis apa yang dimaksud dengan kueri ORM Anda pada akhirnya dan karenanya memverifikasi logika atau bahkan untuk debugging saat tidak menggunakan ORM.
Tidak melakukan level normalisasi yang benar . Anda ingin memastikan bahwa data tidak digandakan, dan bahwa Anda membagi data menjadi berbeda sesuai kebutuhan. Anda juga perlu memastikan Anda tidak mengikuti normalisasi terlalu jauh karena itu akan merusak kinerja.
Memperlakukan basis data hanya sebagai mekanisme penyimpanan (yaitu perpustakaan koleksi yang dimuliakan) dan karenanya tunduk pada aplikasi mereka (mengabaikan aplikasi lain yang berbagi data)
1 - Tidak perlu menggunakan fungsi pada nilai di mana klausa dengan hasil indeks yang tidak digunakan.
Contoh:
where to_char(someDate,'YYYYMMDD') between :fromDate and :toDate
dari pada
where someDate >= to_date(:fromDate,'YYYYMMDD') and someDate < to_date(:toDate,'YYYYMMDD')+1
Dan pada tingkat lebih rendah: Tidak menambahkan indeks fungsional ke nilai-nilai yang membutuhkannya ...
2 - Tidak menambahkan batasan pemeriksaan untuk memastikan validitas data. Kendala dapat digunakan oleh pengoptimal kueri, dan mereka BENAR-BENAR membantu untuk memastikan bahwa Anda dapat mempercayai invarian Anda. Tidak ada alasan untuk tidak menggunakannya.
3 - Menambahkan kolom yang tidak dinormalisasi ke tabel karena kemalasan murni atau tekanan waktu. Hal-hal biasanya tidak dirancang dengan cara ini, tetapi berkembang menjadi ini. Hasil akhirnya, tanpa gagal, adalah satu ton pekerjaan yang mencoba untuk membersihkan kekacauan ketika Anda digigit oleh hilangnya integritas data dalam evolusi masa depan.
Pikirkan ini, tabel tanpa data sangat murah untuk dirancang ulang. Meja dengan beberapa juta catatan tanpa integritas ... tidak terlalu murah untuk dirancang ulang. Dengan demikian, melakukan desain yang benar saat membuat kolom atau tabel diamortisasi dalam sekop.
4 - tidak begitu banyak tentang database per se tetapi memang menjengkelkan. Tidak peduli dengan kualitas kode SQL. Fakta bahwa SQL Anda diekspresikan dalam teks tidak membuatnya OK untuk menyembunyikan logika dalam tumpukan algoritma manipulasi string. Sangat mungkin untuk menulis SQL dalam teks dengan cara yang sebenarnya dapat dibaca oleh sesama programmer Anda.
Ini telah dikatakan sebelumnya, tetapi: indeks, indeks, indeks . Saya telah melihat begitu banyak kasus aplikasi web perusahaan yang berkinerja buruk yang diperbaiki dengan hanya melakukan sedikit profil (untuk melihat tabel mana yang banyak terkena), dan kemudian menambahkan indeks pada tabel tersebut. Ini bahkan tidak memerlukan banyak cara pengetahuan menulis SQL, dan hasilnya sangat besar.
Hindari duplikasi data seperti wabah. Beberapa orang menganjurkan bahwa duplikasi kecil tidak akan sakit, dan akan meningkatkan kinerja. Hei, saya tidak mengatakan bahwa Anda harus menyiksa skema Anda ke dalam Bentuk Normal Ketiga, sampai begitu abstrak sehingga bahkan DBA tidak tahu apa yang terjadi. Hanya mengerti bahwa setiap kali Anda menduplikasi satu set nama, atau kode pos, atau kode pengiriman, salinan-salinan tersebut pada akhirnya tidak akan selaras satu sama lain. Itu akan terjadi. Dan kemudian Anda akan menendang diri sendiri saat Anda menjalankan skrip pemeliharaan mingguan.
Dan terakhir: gunakan konvensi penamaan yang jelas, konsisten, intuitif. Dengan cara yang sama bahwa sepotong kode yang ditulis dengan baik harus dapat dibaca, skema atau kueri SQL yang baik harus dapat dibaca dan secara praktis memberi tahu Anda apa yang dilakukannya, bahkan tanpa komentar. Anda akan berterima kasih pada diri sendiri dalam enam bulan, ketika Anda harus melakukan perawatan di atas meja. "SELECT account_number, billing_date FROM national_accounts"
jauh lebih mudah untuk digunakan daripada "SELECT ACCNTNBR, BILLDAT FROM NTNLACCTS".
Kesalahan paling umum yang pernah saya lihat dalam dua puluh tahun: tidak merencanakan ke depan. Banyak pengembang akan membuat database, dan tabel, dan kemudian terus-menerus memodifikasi dan memperluas tabel saat mereka membangun aplikasi. Hasil akhirnya seringkali berantakan dan tidak efisien serta sulit dibersihkan atau disederhanakan nantinya.
a) Nilai kueri Hardcoding dalam string
b) Menempatkan kode kueri basis data dalam aksi "OnButtonPress" dalam aplikasi Windows Forms
Saya telah melihat keduanya.
Tidak cukup memperhatikan pengelolaan koneksi database di aplikasi Anda. Kemudian Anda mengetahui aplikasi, komputer, server, dan jaringan yang tersumbat.
Berpikir bahwa mereka adalah DBA dan pemodel / desainer data ketika mereka tidak memiliki indoktrinasi formal apa pun di bidang-bidang tersebut.
Berpikir bahwa proyek mereka tidak memerlukan DBA karena hal-hal itu mudah / sepele.
Kegagalan untuk membedakan antara pekerjaan yang seharusnya dilakukan dalam database, dan pekerjaan yang harus dilakukan dalam aplikasi.
Tidak memvalidasi cadangan, atau tidak mencadangkan.
Menanamkan SQL mentah dalam kode mereka.
Berikut ini tautan ke video yang disebut ' Kesalahan Pengembangan Basis Data Klasik dan lima cara untuk mengatasinya ' oleh Scott Walz
Tidak memiliki pemahaman tentang model konkurensi database dan bagaimana ini mempengaruhi pengembangan. Sangat mudah untuk menambahkan indeks dan men-tweak permintaan setelah fakta. Namun aplikasi yang dirancang tanpa pertimbangan yang tepat untuk hotspot, pertentangan sumber daya dan operasi yang benar (Dengan asumsi apa yang baru saja Anda baca masih valid!) Dapat memerlukan perubahan signifikan dalam database dan tingkat aplikasi untuk dikoreksi nanti.
Tidak mengerti bagaimana DBMS bekerja di bawah tenda.
Anda tidak dapat menggerakkan tongkat dengan benar tanpa memahami cara kerja kopling. Dan Anda tidak dapat memahami cara menggunakan Database tanpa memahami bahwa Anda benar-benar hanya menulis ke file di hard disk Anda.
Secara khusus:
Apakah Anda tahu apa itu Indeks Clustered? Apakah Anda memikirkannya ketika Anda merancang skema Anda?
Apakah Anda tahu cara menggunakan indeks dengan benar? Bagaimana cara menggunakan kembali indeks? Apakah Anda tahu apa itu Indeks Penutupan?
Sangat bagus, Anda memiliki indeks. Seberapa besar 1 baris dalam indeks Anda? Seberapa besar indeks ketika Anda memiliki banyak data? Apakah itu mudah masuk ke memori? Jika tidak, itu tidak berguna sebagai indeks.
Apakah Anda pernah menggunakan EXPLAIN di MySQL? Bagus. Sekarang jujurlah dengan diri sendiri: Apakah Anda mengerti bahkan setengah dari apa yang Anda lihat? Tidak, kamu mungkin tidak. Perbaiki itu.
Apakah Anda memahami Query Cache? Apakah Anda tahu apa yang membuat kueri tidak dapat dijangkau?
Apakah Anda menggunakan MyISAM? Jika Anda MEMBUTUHKAN pencarian teks lengkap, MyISAM adalah omong kosong. Gunakan Sphinx. Kemudian beralih ke Inno.