Di milis Netbeans-indonesia ada yang bertanya bagaimana caranya mentuning performance aplikasi, terutama database kalau menggunakan Hibernate sebagai backend. Proses tuning dengan menambahkan index di database dan melakukan cache untuk data statis seperti master data dan data transaksi yang sering dibaca akan menaikkan performance aplikasi hingga beberapa kali lebih cepat. Dari komponen-komponen aplikasi, database dan koneksi antara database dan aplikasi selalu menjadi bottleneck performance aplikasi, sehingga usaha untuk mempercepat query dengan menambahkan index dan mengurangi hit ke database dengan melakukan caching akan sangat signifikan hasil tuningnya.
Salah satu episode dari software engineering radio (se-radio.net eposode #95) membahas bagaimana guardian.co.uk mengubah arsitektur lama yang status (html) menjadi dinamis menggunakan Hibernate sebagai beck-end. Dengan hit puluhan juta kali setiap harinya, hibernate harus di-cache agar hit ke database menjadi minimal, kalau tidak dicache RDBMS apapun pasti kewalahan melayani segitu besarnya request.
Q : Bagaimana Caranya Menambahkan Index Pada Hibernate sehingga secara otomatis akan ditambahkan ke tabel saya juga?
A : Emang bisa dari Hibernate create index ? Koq saya baca di FAQ-nya[1] koq
ga bisa yah??
[1] https://www.hibernate.org/119.html#A11
A : Tuning itu gampang. Yang sulit dan lama itu profiling, yaitu menemukan bottleneck. Sekali bottleneck ditemukan, google 5 menit juga ketemu cara tuningnya.
Berikut metodologi saya dalam melakukan profiling :
1. Jalankan aplikasi dengan stress test tool, misalnya Apache JMeter.
2. Selama stress test sedang jalan, login ke mysql dan jalankan show processlist berkali-kali. Nanti akan keliatan query mana yang makan waktu lama.|
3. Pilih query yang waktunya paling besar.
4. Jalankan explain select untuk query tersebut untuk melihat bagaimana MySQL menjalankan query tersebut.
http://dev.mysql.com/doc/refman/5.0/en/explain.html
5. Lakukan tuning yang sesuai, misalnya:
- tambahkan index di kolom2 yang sering dipakai di where dan order by
- samakan tipe data dan length untuk kolom2 yang sering dijoin
- ubah urutan join
- perbaiki query-nya di source code aplikasi
6. Kembali ke #1 dan lakukan terus sampe performance-nya acceptable. Gak perlu kenceng, yang penting acceptable.
A : Cuma mau nambahin, langkah-langkah diatas bisa kita  otomatis-kan dengan menggunakan tool namanya *MySQL Monitor*[1] tapi  sayangnya ini berbayar, tapi ga masalah kan klo sekedar utk 7an
profilling diatas, kita bisa register utk dpt trial 30 hari :)
Jadi gunakan waktu 30 hari dengan sebaik-2xnya :D
[1] http://mysql.com/products/enterprise/monitor.html
A : Ups..ketinggalan, ini ada tool juga yg fitur-nya hampir sama ama MySQL Monitor, namanya MySQL Proxy[1] dan ini fitur yg dibawa :
MySQL Proxy is a simple program that sits between your client and MySQL server(s) that can monitor, analyze or transform their communication. Its flexibility allows for a wide variety of uses, including load balancing; failover; query analysis; query filtering and modification; and many more.
Q : btw, boleh tanya kenapa harus bikin bean dulu baru generate ke table, knp ga bikin table dulu di database baru tarik jadiin bean, bukankah dengan begitu, index dan sejenisnya bisa di set tanpa harus tergantung dgn Hibernate??
A : Hanya gaya development saja, dari dua arah bisa dilakukan. Jadi tidak ada alasan khusus, cuma alasan kenyamanan saja ;) .
Saya pribadi lebih memilih jalan tengah, untuk proses generate DDL lebih bagus hasil buatan Hibernate daripada buatan saya manual, soalnya Hibernate sangat teliti dalam membuat foreign key, unique constraint dan seterusnya.
Kemudian kalau index dipasang manual karena hibenarnate gak support. Mungkin hibernate tidak bisa menebak mana table yang akan berkembang besar mana yang tidak. Sehingga proses tuning diserahkan ke system engineer / programmer yang tahu mana data besar yang perlu tuning.
A : Kalo di MySQL, beberapa hal yang harus dilakukan setelah hbm2ddl :
1. Tambah index
2. Refine maxlength, misalnya varchar(255) dijadikan varchar(10)
3. Kolom untuk data enum yang tadinya varchar diganti jadi enum.
Q : ada cara lain untuk tuning performance tanpa menggunakan index?
A : Ada juga proses Tuning dengan hibernate tanpa melibatkan tuning
Database, caranya dengan :
1. Hibernate Second level cache
Hibernate mempunyai level 1 cache yang aktif secara otomatis dan gak bisa dinonaktifkan, level cachenya adalah transaction. Jadi cache akan dihapus setelah 1 transaction selesai.
Misalnya dalam satu transaksi kita bikin query yang melibatkan select user berkali2 atau select systemparameter berkali2, maka select ke 2 akan diambilkan dari cache, tidak hit database sama sekali. Tapi ketika transaction selesai maka cache ini akan dibuang.
Second level cache secara default tidak diaktifkan, harus ada konfigurasi tambahan di hibernate.conf agar level2 cache aktif. Library untuk cachenya pun bisa bermacam2, defaultnya sih ehcache.
Contoh penggunaanya misalkan ada data produk yang tidak sering berubah tapi sering banget dibaca. Bikin konfigurasi untuk mengkaktifkan cache level2 dan daftarkan entity produk ke dalam konfigurasi. Settingan
level2 cache pun bervariasi, kita bisa load semua data dalam table produk ke memory (cache) atau hanya sebagian saja menggunakan algoritma LRU atau FIFO.
Perlu diwaspadai bahwa cache ini harus ada proses invalidate-nya, semua proses update insert atau delete harus lewat Hibernate, kalau ada proses lain yang menginsert data dari belakang, maka hasil insert ini kemungkinan tidak masuk cache kalau kita gunakan metode load semua table ke memory (cache). Kalau ada proses lain yang insert data, maka gunakan algoritma LRU atau FIFO agar kalau data produk tidak ketemu, cache harus lihat ke database baru bilang datanya gak ketemu.
Hal lain yang perlu diwaspadai adalah kalau aplikasi jalan menggunakan Client server, dimana setiap client punya sessionfactory sendiri2, nah arsitektur ini gak memungkinkan adanya proses caching yang efisien,
karena setiap client punya cache sendiri-sendiri. Jalankan aplikasinya dalam arsitektur 3-thier baru deh kerasa cache-nya.
2. Hibernate Search
Proses penampilan data transaksi biasanya dilakukan dengan mengambil data langsung ke database (select), dengan adanya hibernate Search, data transaksi diletakkan di tempat lain dalam bentuk hashset,
sehingga setiap kali aplikasi akan menampilkan data dalam bentuk table, datanya diambil dari hibernate search, tidak ambil data ke table.
Proses pencarian data menggunakan fulltext search, bukan lagi select-from-where. Indexing fulltext search menggunakan apache lucene yang sudah integrate dengan hibernate seach. Ketika user mengklik
salah satu barus dalam table, barulah hit database untuk mendapatkan data full-nya. Kelemahanya adalah data dalam table tidak langsung up-to-date, ada jeda beberapa detik sebelum data yang ada di database
(table) diindex ke hibernate search.
Di aplikasi yang sedang saya kerjakan sih metodenya begitu, agar hit databasenya berkurang ketika menampilkan table (inbox). Masalah terbesar di database adalah ketidak mampuanya untuk scalable secara
horizontal. Kalau database dah pusing dihit sama aplikasi ya harus beli lebih besar lagi. Sedangkan Hibernate Search bisa diletakkan dalam lingkungan cluster dengan menggunakan SAN atau dengan
Distributed file system seperti HDFS dan GFS. Dan sekali lagi, tidak bisa jalan di arsitektur Client server, harus pake 3 thier setidaknya.
Q : Saya tertarik dengan Hibernate Search,  apakah bisa dijelaskan lebih detail lagi mengenai Hal ini?
A : Hmm, biar dijelaskan lebih lanjut sama yang bikin Hibernate Search : Emmanuel Bernard
http://www.manning.com/bernard/
;)
Salam