Jika diibaratkan manusia, database adalah sahabat yang patuh dan mengerti pada setiap perintah yang diberikan, sayangnya terkadang tidak berlaku sebaliknya, kita tidak patuh dan tidak mengerti pada “perintah” yang diberikan database.
Database kadang dapat “mengomel” dengan berbagai cara, bisa jadi dalam bentuk performance yang menurun, pesan kesalahan, atau bahkan hasil laporan yang tidak sesuai. Semua-nya dapat kita minimalisasi, bahkan sebelum hal itu terjadi.
SQL dan RDBMS
Optimasi dapat dilakukan dengan berbagai cara, dengan memahami tuning performance pada database dan best practice dari berbagai sumber, Anda dapat memiliki fundamental yang kuat dalam mengoptimalkan kinerja database.
Beberapa teknik dan metoda mungkin memerlukan perlakuan khusus yang berbeda, tergantung pada database yang Anda gunakan.
Sebagai contoh, peningkatan kinerja bisa dilakukan dari sisi administrasi database seperti konfi gurasi file dan peng-updatean service atau security pack, yang tentunya masing-masing database memiliki keunikan dan teknik tersendiri.
Lalu, dengan pertimbangan kompatibilitas, adakah optimasi yang dapat dilakukan secara umum?
Terdapat seperangkat metode dan teknik yang umum diterapkan saat Anda bekerja dengan RDBMS (Relational Database Management System), mungkin tidak semuanya dapat Anda implementasikan karena sangat tergantung pada lingkungan aplikasi masing-masing, tetapi setidaknya Anda dapat meng-gunakannya sebagai panduan dan referensi untuk membentuk sistem yang terbaik sesuai dengan kondisi yang dihadapi.
Optimasi melalui perintah SQL juga memegang peranan yang tidak kalah penting. Inti dari SQL itu sendiri adalah perintah untuk melakukan pengambilan (retrieval), penambahan (insertion), modifikasi (updating), dan penghapusan (deletion) data, disertai dengan fungsi-fungsi pendukung administrasi dan managemen database.
SQL sendiri merupakan sebuah bahasa atau pemrograman standar untuk RDBMS. Walaupun disebut bahasa, mungkin sedikit janggal saat kita menyebut bahasa pemrograman SQL, lebih familiar jika yang terdengar adalah pemrograman C, Visual Basic, Java, Delphi, dan seterusnya.
Bahasa-bahasa yang disebut belakangan termasuk dalam pemrograman imperative, mudahnya adalah bahasa yang berbentuk instruksi-instruksi inti. Sedangkan, SQL termasuk dalam pemrograman declarative, yang lebih berbentuk kalimat atau pernyataan.
Dalam pengembangannya, SQL terbagi-bagi lagi dalam berbagai extension sehingga melahirkan berbagai sebutan seperti SQL/PSM (Persistent Stored Modules) yang merupakan standar ANSI/ISO, T-SQL (Transact-SQL) dari Microsoft dan SyBase, PL/SQL (PL merupakan singkatan dari Procedural Language) yang digunakan oleh Oracle, yang kemudian dikembangkan lagi menjadi PL/pgSQL yang digunakan PostgreSQL.
Cukup membingungkan, bukan? Untungnya konsep dan elemen-elemen dasar dalam SQL seperti statement, query, expression, ataupun clause tetap berlaku umum pada setiap SQL extension.
Kita cukupkan pembahasan teori sampai di sini, berikut adalah beberapa optimasi sederhana yang dapat Anda lakukan, untuk setidaknya memperbaiki atau mencegah permasalahan, dan meningkatkan performa RDBMS Anda.
Index
Optimasi pertama yang kita bahas adalah permasalahan index, tentu Anda mengetahui bahwa index dapat meningkatkan kecepatan pencarian pada record yang diinginkan. Tetapi, Anda harus cukup selektif dalam memilih field yang perlu di-index, karena tidak semua field memerlukannya.
Ibaratnya membaca buku, proses pencarian atau scan akan membaca dari awal hingga akhir halaman. Pada field yang di-index, pencarian dilakukan secara index scan, atau membaca pada index, tidak langsung pada table yang bersangkutan.
Sementara pencarian yang dilakukan langsung dengan membaca record demi record pada table disebut dengan table scan.
Apakah index scan selalu lebih cepat dibandingkan dengan table scan? Ternyata tidak juga, table scan bisa jadi bekerja lebih cepat saat mengakses record dalam jumlah relatif kecil, ataupun pada saat aplikasi memang memerlukan pembacaan table secara keseluruhan.
Sebaliknya dalam mengakses record yang besar pada field tertentu, index scan dapat mengurangi operasi pembacaan I/O sehingga tidak jarang menghasilkan kinerja yang lebih cepat.
Sebagai patokan, Anda dapat menentukan index pada field yang sering digunakan, misalnya field yang sering diakses oleh klausa WHERE, JOIN, ORDER BY, GROUP BY.
Menentukan Tipe Data
Tipe data merupakan permasalahan yang gampang-gampang susah. Dari sisi daya tampung, tipe data yang terlalu kecil atau sebaliknya terlalu besar bagi suatu field, dapat menimbulkan bom waktu yang menimbulkan masalah seiring dengan pertambahan data yang pesat setiap harinya.
Menentukan tipe data yang tepat memerlukan ketelitian dan analisa yang baik. Sebagai contoh, kita perlu mengetahui kapan kita menggunakan tipe data char atau varchar.
Keduanya menampung karakter, bedanya char menyediakan ukuran penyimpanan yang tetap (fi xed-length), sedangkan varchar menyediakan ukuran penyimpanan sesuai dengan isi data (variable-length).
Patokan umum adalah menggunakan tipe data char jika fi eld tersebut diperuntukkan untuk data dengan panjang yang konsisten. Misalnya kode pos, bulan yang terdiri dari dua digit (01 sampai 12), dan seterusnya. Varchar digunakan jika data yang ingin disimpan memiliki panjang yang bervariasi, atau gunakan varchar(max) jika ukurannya melebihi 8000 byte.
Jangan Izinkan Allow Null
Jika memungkinkan, kurangi penggunaan field yang memperbolehkan nilai null. Sebagai gantinya, Anda dapat memberikan nilai default pada field tersebut.
Nilai null kadang rancu dalam intepretasi programer dan dapat mengakibatkan kesalahan logika pemrograman. Selain itu, field null mengonsumsi byte tambahan sehingga menambah beban pada query yang mengaksesnya.
Query yang Mudah Terbaca
Karena SQL merupakan bahasa declarative, maka tidak mengherankan jika Anda membuat query berbentuk kalimat nan panjang walaupun mungkin hanya untuk keperluan menampilkan satu field!
Jangan biarkan query Anda susah dibaca dan dipahami, kecuali Anda memang berniat membuat pusing siapapun yang melihat query Anda. Query panjang yang ditulis dalam 1baris jelas akan menyulitkan modifi kasi dan pemahaman, akan jauh lebih baik jika Anda menuliskan query dalam format yang mudah dicerna.
Pemilihan huruf besar dan kecil juga dapat mempermudah pembacaan, misalnya dengan konsisten menuliskan keyword SQL dalam huruf kapital, dan tambahkan komentar bilamana diperlukan.
Hindari SELECT *
Select mungkin merupakan keyword yang paling sering digunakan, karena itu optimasi pada perintah SELECT sangat mungkin dapat memperbaiki kinerja aplikasi secara keseluruhan. \
SELECT * digunakan untuk melakukan query semua field yang terdapat pada sebuah table, tetapi jika Anda hanya ingin memproses field tertentu, maka sebaiknya Anda menuliskan field yang ingin diakses saja, sehingga query Anda menjadi SELECT field1, field2, field3 dan seterusnya (jangan pedulikan kode program yang menjadi lebih panjang!). Hal ini akan mengurangi beban lalu lintas jaringan dan lock pada table, terutama jika table tersebut memiliki banyak field dan berukuran besar.
Batasi ORDER BY
Penggunaan ORDER BY yang berfungsi untuk mengurutkan data, ternyata memiliki konsekuensi menambah beban query, karena akan menambah satu proses lagi, yaitu proses sort.
Karena itu gunakan ORDER BY hanya jika benar-benar dibutuhkan oleh aplikasi Anda.
Atau jika dimungkinkan, Anda dapat melakukan pengurutan pada sisi client dan tidak pada sisi server. Misalnya dengan menampung data terlebih dahulu pada komponen grid dan melakukan sortir pada grid tersebut sesuai kebutuhan pengguna.
Subquery Atau JOIN
Adakalanya sebuah instruksi dapat dituliskan dalam bentuk subquery atau perintah JOIN, disarankan Anda memprioritaskan penggunaan JOIN karena dalam kasus yang umum akan menghasilkan performa yang lebih cepat.
Walaupun demikian, mengolah query merupakan suatu seni, selalu ada kemungkinan ternyata subquery bekerja lebih cepat dibandingkan JOIN, misalnya dalam kondisi penggunaan
JOIN yang terlalu banyak, ataupun logika query yang belum optimal.
Gunakan WHERE dalam SELECT
“Di mana ada gula di sana ada semut”. Untuk programer database, pepatah itu perlu dimodifi kasi menjadi “di mana ada SELECT di sana ada WHERE”, untuk mengingatkan pentingnya klausa WHERE sebagai kondisi untuk menyaring record sehingga meminimalkan beban jaringan.
Saat sebuah table dengan jumlah data yang sangat besar diproses, juga terjadi proses lock terhadap table tersebut sehingga menyulitkan pengaksesan table yang bersangkutan oleh pengguna yang lain.
Bahkan jika Anda bermaksud memanggil seluruh record, tetap menggunakan WHERE merupakan kebiasaan yang baik.
Jika Anda telah menggunakan WHERE pada awal query, maka kapanpun Anda ingin menambahkan kondisi tertentu, Anda tinggal menyambung query tersebut dengan klausa AND diikuti kondisi yang diinginkan.
Tapi bagaimana menggunakan WHERE jika benar-benar tidak ada kondisi apapun? Anda dapat menuliskan suatu kondisi yang pasti bernilai true, misalnya SELECT .... WHERE 1=1. Bahkan tools open source phpMyAdmin yang berfungsi untuk mena ngani database MySQL selalu menyertakan default klausa WHERE 1 pada perintah SELECT, di mana angka 1 pada MySQL berarti nilai true.
Kecepatan Akses Operator
WHERE 1=1 dan WHERE 0 <> 1 sama-sama merupakan kondisi yang menghasilkan nilai true. Tetapi, dalam hal ini lebih baik Anda menggunakan WHERE 1=1 daripada WHERE 0 <> 1. Hal ini dikarenakan operator = diproses lebih cepat dibandingkan dengan operator <>.
Dari sisi kinerja, urutan operator yang diproses paling cepat adalah:
1. =
2. >, >=, <. <=
3. LIKE
4. <>
Tidak dalam setiap kondisi operator dapat disubtitusikan seperti contoh sederhana di atas, tetapi prioritaskanlah penggunaan operator yang tercepat.
Membatasi Jumlah Record
Bayangkan Anda menampilkan isi sebuah table dengan menggunakan SELECT, dan ternyata table tersebut memiliki jutaan record yang sangat tidak diharapkan untuk tampil seluruhnya.
Skenario yang lebih buruk masih dapat terjadi, yaitu query tersebut diakses oleh ratusan pengguna lain dalam waktu bersamaan!
Untuk itu, Anda perlu membatasi jumlah record yang berpotensi mengembalikan record dalam jumlah besar (kecuali memang benar-benar dibutuhkan), pada SQL Server, Anda dapat menggunakan operator TOP di dalam perintah SELECT.
Contohnya SELECT TOP 100 nama... akan menampilkan 100 record teratas field nama.
Jika menggunakan MySQL, Anda dapat menggunakan LIMIT untuk keperluan yang sama.
Database kadang dapat “mengomel” dengan berbagai cara, bisa jadi dalam bentuk performance yang menurun, pesan kesalahan, atau bahkan hasil laporan yang tidak sesuai. Semua-nya dapat kita minimalisasi, bahkan sebelum hal itu terjadi.
SQL dan RDBMS
Optimasi dapat dilakukan dengan berbagai cara, dengan memahami tuning performance pada database dan best practice dari berbagai sumber, Anda dapat memiliki fundamental yang kuat dalam mengoptimalkan kinerja database.
Beberapa teknik dan metoda mungkin memerlukan perlakuan khusus yang berbeda, tergantung pada database yang Anda gunakan.
Sebagai contoh, peningkatan kinerja bisa dilakukan dari sisi administrasi database seperti konfi gurasi file dan peng-updatean service atau security pack, yang tentunya masing-masing database memiliki keunikan dan teknik tersendiri.
Lalu, dengan pertimbangan kompatibilitas, adakah optimasi yang dapat dilakukan secara umum?
Terdapat seperangkat metode dan teknik yang umum diterapkan saat Anda bekerja dengan RDBMS (Relational Database Management System), mungkin tidak semuanya dapat Anda implementasikan karena sangat tergantung pada lingkungan aplikasi masing-masing, tetapi setidaknya Anda dapat meng-gunakannya sebagai panduan dan referensi untuk membentuk sistem yang terbaik sesuai dengan kondisi yang dihadapi.
Optimasi melalui perintah SQL juga memegang peranan yang tidak kalah penting. Inti dari SQL itu sendiri adalah perintah untuk melakukan pengambilan (retrieval), penambahan (insertion), modifikasi (updating), dan penghapusan (deletion) data, disertai dengan fungsi-fungsi pendukung administrasi dan managemen database.
SQL sendiri merupakan sebuah bahasa atau pemrograman standar untuk RDBMS. Walaupun disebut bahasa, mungkin sedikit janggal saat kita menyebut bahasa pemrograman SQL, lebih familiar jika yang terdengar adalah pemrograman C, Visual Basic, Java, Delphi, dan seterusnya.
Bahasa-bahasa yang disebut belakangan termasuk dalam pemrograman imperative, mudahnya adalah bahasa yang berbentuk instruksi-instruksi inti. Sedangkan, SQL termasuk dalam pemrograman declarative, yang lebih berbentuk kalimat atau pernyataan.
Dalam pengembangannya, SQL terbagi-bagi lagi dalam berbagai extension sehingga melahirkan berbagai sebutan seperti SQL/PSM (Persistent Stored Modules) yang merupakan standar ANSI/ISO, T-SQL (Transact-SQL) dari Microsoft dan SyBase, PL/SQL (PL merupakan singkatan dari Procedural Language) yang digunakan oleh Oracle, yang kemudian dikembangkan lagi menjadi PL/pgSQL yang digunakan PostgreSQL.
Cukup membingungkan, bukan? Untungnya konsep dan elemen-elemen dasar dalam SQL seperti statement, query, expression, ataupun clause tetap berlaku umum pada setiap SQL extension.
Kita cukupkan pembahasan teori sampai di sini, berikut adalah beberapa optimasi sederhana yang dapat Anda lakukan, untuk setidaknya memperbaiki atau mencegah permasalahan, dan meningkatkan performa RDBMS Anda.
Index
Optimasi pertama yang kita bahas adalah permasalahan index, tentu Anda mengetahui bahwa index dapat meningkatkan kecepatan pencarian pada record yang diinginkan. Tetapi, Anda harus cukup selektif dalam memilih field yang perlu di-index, karena tidak semua field memerlukannya.
Ibaratnya membaca buku, proses pencarian atau scan akan membaca dari awal hingga akhir halaman. Pada field yang di-index, pencarian dilakukan secara index scan, atau membaca pada index, tidak langsung pada table yang bersangkutan.
Sementara pencarian yang dilakukan langsung dengan membaca record demi record pada table disebut dengan table scan.
Apakah index scan selalu lebih cepat dibandingkan dengan table scan? Ternyata tidak juga, table scan bisa jadi bekerja lebih cepat saat mengakses record dalam jumlah relatif kecil, ataupun pada saat aplikasi memang memerlukan pembacaan table secara keseluruhan.
Sebaliknya dalam mengakses record yang besar pada field tertentu, index scan dapat mengurangi operasi pembacaan I/O sehingga tidak jarang menghasilkan kinerja yang lebih cepat.
Sebagai patokan, Anda dapat menentukan index pada field yang sering digunakan, misalnya field yang sering diakses oleh klausa WHERE, JOIN, ORDER BY, GROUP BY.
Menentukan Tipe Data
Tipe data merupakan permasalahan yang gampang-gampang susah. Dari sisi daya tampung, tipe data yang terlalu kecil atau sebaliknya terlalu besar bagi suatu field, dapat menimbulkan bom waktu yang menimbulkan masalah seiring dengan pertambahan data yang pesat setiap harinya.
Menentukan tipe data yang tepat memerlukan ketelitian dan analisa yang baik. Sebagai contoh, kita perlu mengetahui kapan kita menggunakan tipe data char atau varchar.
Keduanya menampung karakter, bedanya char menyediakan ukuran penyimpanan yang tetap (fi xed-length), sedangkan varchar menyediakan ukuran penyimpanan sesuai dengan isi data (variable-length).
Patokan umum adalah menggunakan tipe data char jika fi eld tersebut diperuntukkan untuk data dengan panjang yang konsisten. Misalnya kode pos, bulan yang terdiri dari dua digit (01 sampai 12), dan seterusnya. Varchar digunakan jika data yang ingin disimpan memiliki panjang yang bervariasi, atau gunakan varchar(max) jika ukurannya melebihi 8000 byte.
Jangan Izinkan Allow Null
Jika memungkinkan, kurangi penggunaan field yang memperbolehkan nilai null. Sebagai gantinya, Anda dapat memberikan nilai default pada field tersebut.
Nilai null kadang rancu dalam intepretasi programer dan dapat mengakibatkan kesalahan logika pemrograman. Selain itu, field null mengonsumsi byte tambahan sehingga menambah beban pada query yang mengaksesnya.
Query yang Mudah Terbaca
Karena SQL merupakan bahasa declarative, maka tidak mengherankan jika Anda membuat query berbentuk kalimat nan panjang walaupun mungkin hanya untuk keperluan menampilkan satu field!
Jangan biarkan query Anda susah dibaca dan dipahami, kecuali Anda memang berniat membuat pusing siapapun yang melihat query Anda. Query panjang yang ditulis dalam 1baris jelas akan menyulitkan modifi kasi dan pemahaman, akan jauh lebih baik jika Anda menuliskan query dalam format yang mudah dicerna.
Pemilihan huruf besar dan kecil juga dapat mempermudah pembacaan, misalnya dengan konsisten menuliskan keyword SQL dalam huruf kapital, dan tambahkan komentar bilamana diperlukan.
Hindari SELECT *
Select mungkin merupakan keyword yang paling sering digunakan, karena itu optimasi pada perintah SELECT sangat mungkin dapat memperbaiki kinerja aplikasi secara keseluruhan. \
SELECT * digunakan untuk melakukan query semua field yang terdapat pada sebuah table, tetapi jika Anda hanya ingin memproses field tertentu, maka sebaiknya Anda menuliskan field yang ingin diakses saja, sehingga query Anda menjadi SELECT field1, field2, field3 dan seterusnya (jangan pedulikan kode program yang menjadi lebih panjang!). Hal ini akan mengurangi beban lalu lintas jaringan dan lock pada table, terutama jika table tersebut memiliki banyak field dan berukuran besar.
Batasi ORDER BY
Penggunaan ORDER BY yang berfungsi untuk mengurutkan data, ternyata memiliki konsekuensi menambah beban query, karena akan menambah satu proses lagi, yaitu proses sort.
Karena itu gunakan ORDER BY hanya jika benar-benar dibutuhkan oleh aplikasi Anda.
Atau jika dimungkinkan, Anda dapat melakukan pengurutan pada sisi client dan tidak pada sisi server. Misalnya dengan menampung data terlebih dahulu pada komponen grid dan melakukan sortir pada grid tersebut sesuai kebutuhan pengguna.
Subquery Atau JOIN
Adakalanya sebuah instruksi dapat dituliskan dalam bentuk subquery atau perintah JOIN, disarankan Anda memprioritaskan penggunaan JOIN karena dalam kasus yang umum akan menghasilkan performa yang lebih cepat.
Walaupun demikian, mengolah query merupakan suatu seni, selalu ada kemungkinan ternyata subquery bekerja lebih cepat dibandingkan JOIN, misalnya dalam kondisi penggunaan
JOIN yang terlalu banyak, ataupun logika query yang belum optimal.
Gunakan WHERE dalam SELECT
“Di mana ada gula di sana ada semut”. Untuk programer database, pepatah itu perlu dimodifi kasi menjadi “di mana ada SELECT di sana ada WHERE”, untuk mengingatkan pentingnya klausa WHERE sebagai kondisi untuk menyaring record sehingga meminimalkan beban jaringan.
Saat sebuah table dengan jumlah data yang sangat besar diproses, juga terjadi proses lock terhadap table tersebut sehingga menyulitkan pengaksesan table yang bersangkutan oleh pengguna yang lain.
Bahkan jika Anda bermaksud memanggil seluruh record, tetap menggunakan WHERE merupakan kebiasaan yang baik.
Jika Anda telah menggunakan WHERE pada awal query, maka kapanpun Anda ingin menambahkan kondisi tertentu, Anda tinggal menyambung query tersebut dengan klausa AND diikuti kondisi yang diinginkan.
Tapi bagaimana menggunakan WHERE jika benar-benar tidak ada kondisi apapun? Anda dapat menuliskan suatu kondisi yang pasti bernilai true, misalnya SELECT .... WHERE 1=1. Bahkan tools open source phpMyAdmin yang berfungsi untuk mena ngani database MySQL selalu menyertakan default klausa WHERE 1 pada perintah SELECT, di mana angka 1 pada MySQL berarti nilai true.
Kecepatan Akses Operator
WHERE 1=1 dan WHERE 0 <> 1 sama-sama merupakan kondisi yang menghasilkan nilai true. Tetapi, dalam hal ini lebih baik Anda menggunakan WHERE 1=1 daripada WHERE 0 <> 1. Hal ini dikarenakan operator = diproses lebih cepat dibandingkan dengan operator <>.
Dari sisi kinerja, urutan operator yang diproses paling cepat adalah:
1. =
2. >, >=, <. <=
3. LIKE
4. <>
Tidak dalam setiap kondisi operator dapat disubtitusikan seperti contoh sederhana di atas, tetapi prioritaskanlah penggunaan operator yang tercepat.
Membatasi Jumlah Record
Bayangkan Anda menampilkan isi sebuah table dengan menggunakan SELECT, dan ternyata table tersebut memiliki jutaan record yang sangat tidak diharapkan untuk tampil seluruhnya.
Skenario yang lebih buruk masih dapat terjadi, yaitu query tersebut diakses oleh ratusan pengguna lain dalam waktu bersamaan!
Untuk itu, Anda perlu membatasi jumlah record yang berpotensi mengembalikan record dalam jumlah besar (kecuali memang benar-benar dibutuhkan), pada SQL Server, Anda dapat menggunakan operator TOP di dalam perintah SELECT.
Contohnya SELECT TOP 100 nama... akan menampilkan 100 record teratas field nama.
Jika menggunakan MySQL, Anda dapat menggunakan LIMIT untuk keperluan yang sama.