大數據量查詢速慢

最近在作一個簡單的管理系統 , 在最後收尾時數據庫裏的記錄增大到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

相關文章
相關標籤/搜索