JAVA中四种SQL执行方式性能测试

在这个项目中,由于一些原因没有使用orm进行数据库操作,而是使用Spring的JdbcTemplate

但在上线后发现效率很低,通过性能监视器发现SQL Compilations的比率很高,程序中大量使用动态拼SQL语句的情况

于是进行了一些性能测试

 

代码如下:

 

		Main.log("SQL四种执行方式性能比较");
		// Statement
		jt.execute("dbcc freeproccache");
		start = System.currentTimeMillis();
		sql = "select top {0} id, intStatus from tblInfo where charCityFrom=''{1}''";
		for (int i = citys.size() -1; i >= 0; i--) {
			Map c = citys.get(i);
			String city = (String) c.get("charCityFrom");
			jt.queryForList(MessageFormat.format(sql, i % 20 + 1, city));
		}
		map = jt.queryForMap("Select Count(*) CNT,sum(size_in_bytes) TotalSize From sys.dm_exec_cached_plans");
		Main.log("Statement:CNT=" + map.get("CNT") + " TotalSize=" + map.get("TotalSize"), start);
		
		// PreparedStatement
		jt.execute("dbcc freeproccache");
		start = System.currentTimeMillis();
		sql = "select top {0} id, intStatus from tblInfo where charCityFrom=?";
		for (int i = citys.size() -1; i >= 0; i--) {
			Map c = citys.get(i);
			String city = (String) c.get("charCityFrom");
			jt.queryForList(MessageFormat.format(sql, i % 20 + 1), new Object[]{city});
		}
		map = jt.queryForMap("Select Count(*) CNT,sum(size_in_bytes) TotalSize From sys.dm_exec_cached_plans");
		Main.log("PreparedStatement:CNT=" + map.get("CNT") + " TotalSize=" + map.get("TotalSize"), start);
		
		// EXEC sp_executesql
		jt.execute("dbcc freeproccache");
		start = System.currentTimeMillis();
		sql = "EXEC sp_executesql N''select top {0} id, intStatus from tblInfo where charCityFrom=@cityFrom'', N''@cityFrom nvarchar(10)'', ''{1}''";
		for (int i = citys.size() -1; i >= 0; i--) {
			Map c = citys.get(i);
			String city = (String) c.get("charCityFrom");
			jt.queryForList(MessageFormat.format(sql, i % 20 + 1, city));
		}
		map = jt.queryForMap("Select Count(*) CNT,sum(size_in_bytes) TotalSize From sys.dm_exec_cached_plans");
		Main.log("Sp_executesql:CNT=" + map.get("CNT") + " TotalSize=" + map.get("TotalSize"), start);
		
		// 存储过程
		jt.execute("dbcc freeproccache");
		start = System.currentTimeMillis();
		sql = "exec sp_FindInfoByCitFrom {0},''{1}''";
		for (int i = citys.size() -1; i >= 0; i--) {
			Map c = citys.get(i);
			String city = (String) c.get("charCityFrom");
			jt.queryForList(MessageFormat.format(sql, i % 20 + 1, city));
		}
		map = jt.queryForMap("Select Count(*) CNT,sum(size_in_bytes) TotalSize From sys.dm_exec_cached_plans");
		Main.log("Procedure:CNT=" + map.get("CNT") + " TotalSize=" + map.get("TotalSize"), start);

 

 得到结果(多次执行,结果相关不大):

2008-11-05 10:36:52.521 [main] - SQL四种执行方式性能比较
2008-11-05 10:36:53.365 [main] - Statement:CNT=224 TotalSize=9134080 t=829ms
2008-11-05 10:36:53.815 [main] - PreparedStatement:CNT=23 TotalSize=901120 t=450ms
2008-11-05 10:36:55.44 [main] - Sp_executesql:CNT=26 TotalSize=1351680 t=1625ms
2008-11-05 10:36:55.864 [main] - Procedure:CNT=25 TotalSize=933888 t=424ms

 

 

存储过程虽然性能最高,但维护确实有点麻烦

综合一下就我们的情况使用PreparedStatement最好,不过以前使用sql server 2000时有发现这个性能不好,看来跟生产环境还是有挺大关系

Sp_executesql的表现倒是出乎意料

 

经验主意害死人啊,就这个问题浪费了大量的时间

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值