Bermula dari tugas yang dikasih atasan di kantor untuk menampilkan data sejumlah data yang tidak sedikit dengan entitas yang relasinya juga tidak sedikit .. dan melakukan perhitungan – perhitungan … kalo hanya sekedar menampilkan data saja sih anak TK juga bisa .. hehehe tapi yang jadi masalah adalah jika untuk me load data tersebut membutuhkan waktu hingga ber menit – menit bahkan hingga setengah jam .. user mana yang sabar menunggu … ???? hahah sebenarnya ada beberapa alternatif yang mungkin di tempuh untuk mempercepat akses data seperti yang saya butuhkan … seperti membuat paging, menampilkan data secara parsial (tidak keseluruhan) sesuai dengan tanggal yang dipilih. Namun untuk kasus yang saya alami ini hal tersebut tidak di perbolehkan .. anda tau kenapa .. ? ya ..jawaban gampangnya karena atasan saya bilang tidak boleh di paging atau di tampilkan parsial .. hahaha =))
Oke .. kalo gitu keadaan nya saya punya alternatif lain .. setelah saya lihat Struktur Objeknya ternyata disana menggunakan Hibernate Criteria, kalo begitu gimana kalo kita coba rubah menggunakan SQL saja … hehhehe … dan ternyata memang terjadi perubahan yang cukup signifikan di kantor saya .. oleh karena itu saya akan membuat percobaan sederhana pada posting kali ini tetapi tidak menggunakan data di kantor .. heheheh … saya menggunakan data sederhana .. sebelum itu berikut ini spesifikasi yang digunakan dalam percobaan ini :
- MySQL Version : Ver 14.14 Distrib 5.1.37, for Win32 (ia32)
- Application Server : Jetty 6
- Hibernate Version : Hibernate 3.3.2 GA
- MVC Framework : Spring 3
- Project Builder : Maven 2.2.1
- Web Browser : Mozilla Firefox 15.0.1 (with YSlow and Firebug add-on)
Langkah Pertama yang saya lakukan adalah memasukkan data ke dalam sebuah Tabel yang tidak memiliki relasi dengan jumlah record sebanyak 10.000 record, berikut ini code program untuk memasukkan data contoh nya tersebut :
itemCategory_test.jsp
<%@ include file="../taglibs.jsp"%> <c:set var="base" value="${ctx }itemCategory" /> <h3>Test Speed </h3> <form:form modelAttribute="itemCategory" method="POST" action="${ base }/testSpeed"> <table border="0" width="100%" height="50px"> <tr> <td colspan="3" align="right"> <input class="btn btn-primary" type="submit" value="Insert 10000 Data"> </td> </tr> <tr> <td colspan="3" align="center"> <input type="button" class="btn btn-small btn-primary" value="Criteria" onclick="viewByCriteria();"/> <input type="button" class="btn btn-small btn-primary" value="HQL" onclick="viewByHql();"/> <input type="button" class="btn btn-small btn-primary" value="SQL" onclick="viewBySql();"/> </td> </tr> <c:forEach items="${itemCategoryList}" var="itemCategory" varStatus="vs"> <tr> <td> ${vs.count } </td> <td colspan="2"> ${itemCategory.name } </td> </tr> </c:forEach> </table> </form:form> <script type="text/javascript"> function viewByCriteria(){ var url = '${base}/testSpeed?version=criteria'; window.location=url; } function viewByHql(){ var url = '${base}/testSpeed?version=hql'; window.location=url; } function viewBySql(){ var url = '${base}/testSpeed?version=sql'; window.location=url; } </script>
ItemCategoryController.java
@RequestMapping(value = "/testSpeed", method = RequestMethod.POST) public String performTestSpeedPost(@ModelAttribute ItemCategory itemCategory){ try { itemCategory.setName("Test Speed Hibernate SQL"); for(int i = 1; i<=10000; i++){ itemCategoryService.save(itemCategory); } } catch (Exception e) { e.printStackTrace(); } return "redirect:/itemCategory/testSpeed"; }
Untuk menginsert data sebanyak 10.000 record ternyata cukup lama juga … membutuhkan waktu 406.532 S yang diukur menggunakan Firebug dan YSlow add on dari Mozilla Firefox ..
Nah setelah Data di input sekarang tinggal membuat tiga method dengan menggunakan Hibernate Criteria, HQL dan SQL berikut ini method nya :
public List<ItemCategory> getAll() {//menggunakan criteria Criteria q = getCurrentSession().createCriteria(ItemCategory.class); return q.list(); } public List<ItemCategory> getAllHql(){//menggunakan hql Query q = getCurrentSession().createQuery("FROM ItemCategory"); return q.list(); } public List<ItemCategory> getAllSql(){//menggunakan sql String sql = "SELECT ic.id, ic.name FROM itemCategory ic "; Query q = getCurrentSession().createSQLQuery(sql) .addScalar("id", Hibernate.LONG) .addScalar("name", Hibernate.STRING) .setResultTransformer(new AliasToBeanResultTransformer(ItemCategory.class)); return q.list(); }
nah sekarang tinggal membuat method untuk menampilkan hasil query berdasarkan parameter yang dikirim dari JSP … check this ! :
@RequestMapping(value = "/testSpeed", method = RequestMethod.GET) public String performTestSpeed(Model model, @RequestParam (required = false) String version){ try { List <ItemCategory> itemCategory = new LinkedList<ItemCategory>(); if(!Utils.isEmpty(version) && version.equalsIgnoreCase("Criteria")){ System.out.println("masuk criteria"); itemCategory = itemCategoryService.getAll(); } if(!Utils.isEmpty(version) && version.equalsIgnoreCase("Hql")){ System.out.println("masuk Hql"); itemCategory = itemCategoryService.getAllHql(); } if(!Utils.isEmpty(version) && version.equalsIgnoreCase("Sql")){ System.out.println("masuk sql"); itemCategory = itemCategoryService.getAllSql(); } model.addAttribute("itemCategory", new ItemCategory()); model.addAttribute("itemCategoryList", itemCategory); } catch (Exception e) { e.printStackTrace(); } return "itemCategory.test"; }
and Finally sekarang tinggal klik Criteria, Hql, atau SQl … pada percobaan ini untuk setiap Opsi (Criteria, Hql, Sql) saya mengujinya sebanyak 3x sehingga di dapat tabel pengujian seperti dibawah ini :
Dari tabel diatas terlihat bahwa menggunakan SQL lebih cepat dibandingkan HQL dan juga Criteria walaupun terlihat tidak terlalu signifikan perbedaannya .. tetapi perlu diingat bahwa entitas dalam percobaan ini adalah tabel yang tidak berelasi sama sekali.. dan menurut pengalaman saya ketika membandingkan Hibernate Criteria dengan SQL pada Entitas yang mempunyai banyak sekali relasi perbedaan kecepatan akses data akan sangat terasa sekali … So kesimpulannya kalo sekiranya pake Hibernate Criteria terasa lama ga karuan .. ga apa2 koq back to SQL .. yang penting kinerja program yang kita buat bisa lebih optimal … Good Luck .. !