最近在作一个简单的管理系统 , 在最后收尾时数据库里的记录增大到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