最近在作一個簡單的管理系統 , 在最後收尾時數據庫裏的記錄增大到200萬時,分頁查詢時發現速度很是慢,一直在找緣由 , 起初覺得是hibernate的問題,後來跟蹤源碼到jdbc層次發現不是hibernate的緣由.下面貼出部分代碼 . java
getHibernateTemplate().execute( new HibernateCallback<List<LoginLogDTO>>() { @Override public List<LoginLogDTO> doInHibernate(Session session) throws HibernateException, SQLException { StringBuilder sqlBuilder = new StringBuilder(); sqlBuilder .append("select ll.log_id , ll.uuid , m.product_name , p.platform_name , ll.create_time "); sqlBuilder .append(" , ll.operate_type , ll.soft_vers_no "); sqlBuilder .append(" from t_login_log ll left join t_model_platform mp on ll.mode_plat_id=mp.mode_plat_id "); sqlBuilder .append(" left join t_model m on mp.model_id = m.model_id "); sqlBuilder .append(" left join t_platform p on p.platform_code = mp.platform_code where 1=1 "); // 搜索條件 if (StringUtils.equals(findTypes[0], findType)) { sqlBuilder.append(" and ll.uuid=:numValue"); } else if (StringUtils.equals(findTypes[1], findType)) { sqlBuilder .append(" and m.product_name=:stringValue"); } else if (StringUtils.equals(findTypes[2], findType)) { sqlBuilder .append(" and p.platform_name=:stringValue"); } else if (StringUtils.equals(findTypes[3], findType)) { sqlBuilder .append(" and ll.operate_type=:numValue"); } // date if (startDate != null) { // sqlBuilder.append(" and ll.create_time >= :startDate ");//慢的寫法 sqlBuilder.append(" and ll.create_time >=to_date(:startDate , 'yyyy-mm-dd hh24:mi:ss') "); } if (endDate != null) { // sqlBuilder.append(" and ll.create_time <= :endDate "); sqlBuilder.append(" and ll.create_time <=to_date(:endDate , 'yyyy-mm-dd hh24:mi:ss') "); } try { Query query = session.createSQLQuery(sqlBuilder.toString()) ; if(ArrayUtils.contains(findTypes, findType)){ if(StringUtils.equals(findTypes[0], findType)){ query.setLong("numValue", Long.valueOf(findValue)) ; } else if(StringUtils.equals(findTypes[3], findType)) { if("登陸".equals(findValue)) query.setShort("numValue", (short)1) ; else if ("退出".equals(findValue)) { query.setShort("numValue", (short)2) ; } else { query.setShort("numValue", (short)-1) ; } } else{ query.setString("stringValue", findValue) ; } } if(startDate!=null){ // query.setTimestamp("startDate", startDate) ; //njl query.setString("startDate", DateFormatUtils.format(startDate, "yyyy-MM-dd HH:mm:ss")) ; } if(endDate!=null){ // query.setTimestamp("endDate", endDate) ; query.setString("endDate", DateFormatUtils.format(endDate, "yyyy-MM-dd HH:mm:ss")) ; } query.setFirstResult(firstResult) ; query.setMaxResults(maxResults) ; List<LoginLogDTO> llList = new ArrayList<LoginLogDTO>() ; long start = System.currentTimeMillis() ; List<Object[]> result = query.list() ; log.debug("query login log spend: " + (System.currentTimeMillis() - start) + "ms") ; return llList; } catch (NumberFormatException e) { e.printStackTrace(); throw new IllegalArgumentException() ; } catch (HibernateException e) { log.error("query login log error ") ; e.printStackTrace() ; throw new DAOException(e) ; } } });
t_login_log表中有200萬條記錄 , 其它表中數據不多sql
若是在設置參數時 , 使用query.setTimestamp("startDate" , startDate) ;要花費2000ms若是改爲上面的寫法用了4ms左右.數據庫
記錄一下 , 可能不session