Pengoptimalan kinerja SQL merupakan tantangan besar bagi pemrogram, karena kita sering menghadapi masalah ini: ketika kita mengembangkan sebuah proyek, kita merasa bahwa pengalaman fungsional mengujinya sendiri sangat bagus, tetapi setelah proyek sebenarnya diluncurkan, Dengan peningkatan yang sangat besar dalam data, pengalaman pelanggan terhadap sistem menjadi semakin buruk. Tentu saja, selain framework dan kode yang tidak masuk akal, alasan utamanya adalah SQL belum dioptimalkan, yang menyebabkan sistem menjadi semakin lambat.
Karena saya bekerja di sebuah perusahaan kecil, saya melakukan segalanya. Saya pikir terkadang lebih baik mengobati gejalanya daripada mengobati akar masalahnya! Ada beberapa hal yang perlu diperhatikan:
1. Desain tabel database harus masuk akal, terutama desain kunci utama. Jika jumlah data dalam tabel sangat besar, maka desain kunci utama tidak boleh bermakna, seperti halnya ROWID. GUID SQL Server, UUID Hibernate, dll. Tentu saja, beberapa tabel kamus data dapat diproses secara fleksibel, dan tidak perlu mempertimbangkan bahwa tabel tersebut harus berupa kunci utama fisik. Dalam desain kunci primer, kunci primer komposit umumnya tidak digunakan.
2. Pengindeksan yang wajar. Indeks adalah alat yang ampuh dan sarana yang baik untuk mempercepat permintaan data kami. Tapi jangan tambahkan setiap bidang. Prinsip pengindeksan sama seperti daftar isi sebuah buku, jika daftar isi buku Anda hampir semuanya sama namanya, bayangkan berikut ini seberapa cepat Anda bisa menemukan konten tertentu sesuai daftar isi ? Indeks tidak harus unik, namun tidak boleh memiliki terlalu banyak catatan yang identik. Selain itu, jika lebih banyak indeks ditambahkan, ruang tabel TEMP akan bertambah. Saat mengekspor tabel dan mengimpornya ke database lain, indeks juga akan mengurangi efisiensi impor berukuran sangat besar. Oleh karena itu, indeks adalah pedang bermata dua dan harus diterapkan secara wajar.
3. Saya telah melihat beberapa artikel yang sangat profesional tentang optimasi SQL di Internet, tetapi saya merasa belum dapat menggunakannya dalam proyek saya. Sebaliknya, saya terus bereksperimen dan menemukan beberapa prinsip dasar selama proyek berlangsung. Menurut saya pribadi, hanya ada satu prinsip optimasi SQL, yaitu mempersempit cakupan kueri sebanyak mungkin. Ini pasti akan meningkatkan efisiensi, dan Oracle sendiri dapat mengoptimalkan SQL yang kita tulis, jadi yang harus kita lakukan adalah melakukannya mempersempit cakupan kueri sebanyak mungkin. Berbicara tentang ini, saya rasa semua orang pasti akan berpikir bahwa pengindeksan adalah alat yang ampuh untuk meningkatkan kecepatan kueri .
Sebagian besar SQL yang perlu dioptimalkan adalah kueri gabungan multi-tabel, dan gabungan multi-tabel juga mencakup gabungan horizontal dan gabungan vertikal. Koneksi horizontal secara umum berarti bahwa struktur bidang dari dua tabel pada dasarnya sama, dan beberapa record data dari satu tabel harus diubah menjadi beberapa record dari tabel lain, yaitu Baris+Baris. Koneksi vertikal artinya kita mengambil beberapa field untuk diquery dari tabel A, dan beberapa field untuk diquery dari tabel B, lalu menghubungkan tabel-tabel yang diambil dari tabel A dan B secara vertikal menggunakan bagian yang sama, yaitu Kolom+Kolom.
Pernyataan gabung horizontal: pilih a.column1,a.column2 dari tableA a union all pilih b.column1,b.column2 dari tableB b
Perhatikan bahwa saat menghubungkan secara horizontal, jumlah kolom harus sama, dan tipe data kolom bidang terkait harus sama. Faktanya, Anda dapat menganggap tabel-tabel yang akan digabungkan sebagai satu salinan dari tabel lainnya, persis sama. Mungkin ada yang bertanya, jika kolom yang ingin saya gabungkan memang memiliki kolom yang berbeda, atau tidak ada kolom sama sekali, maka Anda bisa menggunakan cara berikut ini.
pilih d.dname,d.loc dari dept1 d union semua pilih '' dname, e.loc dari dept e, lihat "'' dname", kita dapat dengan mudah menemukan bahwa Anda dapat menemukan penggantinya, gunakan string kosong sebagai gantinya Di sana tidak ada bidang, sehingga dapat digabungkan.
Pernyataan gabungan vertikal: pilih a.column1,a.column2 dari tabelA gabungan luar penuh pilih b.kolom3,b.kolom4 dari tabelB b pada a.aid=b.bid di mana..., ini adalah Format gabungan luar penuh. Kecepatan ini memang sangat cepat, tetapi Anda mungkin tidak menyukai kueri tersebut, karena ada beberapa baris hasil yang mungkin tidak ingin Anda lihat sama sekali. Dalam keadaan normal, kita lebih banyak menggunakan gabung luar kiri dan gabung luar kanan. Perbedaan antara keduanya adalah gabung luar kiri terutama didasarkan pada tabel yang sesuai dengan bidang gabung di sebelah kiri setelahnya, dan gabung luar kanan justru berlawanan. Tentu saja Anda juga bisa menggunakan gabung kiri, gabung kanan. Selama penggunaan, saya masih menemukan koneksi eksternal relatif lebih cepat.
Untuk mempercepat efisiensi query koneksi vertikal, caranya adalah dengan membuat nest query. Berikut ini adalah contoh nyata dari proyek tersebut:
pilih c.customerid,c.receivedmoney,c.tollcollector,c.receiveddate,c.yearmonth,c.receivedlatefee,
c.biaya yang diterima,c.tambahan yang diterima,c.jmman,c.jmmoney,c.name,d.biaya dari
(pilih a.customerid,a.receivedmoney,a.tollcollector,a.receiveddate,a.yearmonth,a.receivedlatefee,
a.biaya yang diterima,a.tambahan yang diterima,a.jmman,a.jmmoney,b.nama dari
(pilih rf.customerid,rf.receivedmoney,rf.tollcollector,rf.receiveddate,rf.yearmonth,rf.receivedlatefee,
rf.receivedfee,rf.receivedappend,rf.jmman,rf.jmmoney dari sf_receivedfee rf di mana
rf.electriccompanyid='1000000001' dan rf.dealsign=0 dan rf.yearmonth in(200811,200901,200903,200804,200805,200806,200807)
dan rf.customerid=1000052545) gabungan luar kiri (pilih xe.employeeid,xe.name dari xt_employee xe) b pada a.tollcollector=b.employeeid)
c gabung luar kiri (pilih cp.chargeint,cp.customerid dari sf_chargeprotocol cp di mana cp.customerid=1000052545) d
pada c.customerid=d.customerid
Anda dapat melihat bahwa dalam contoh ini, pertama-tama kita memfilter catatan yang kita perlukan dari setiap tabel menggunakan kondisi yang hampir sama, lalu menggabungkan catatan tersebut. Dalam penggunaan sebenarnya, saya menemukan bahwa ini hampir 60 kali lebih cepat daripada kueri tautan langsung. Meskipun jelek dan sulit dibaca, ini memecahkan masalah kinerja SQL. Prinsip yang digunakan masih mempersempit cakupan terlebih dahulu, lalu melakukan query koneksi. Jika kita menghubungkan lalu memfilter, itu setara dengan menggabungkan dua tabel, lalu mengambil data berdasarkan kondisi.