SqlServer高级特性--存储过程
需求:
用户需要提交加密数据,提交之后需要解密还原,还原有两种结果:成功和失败!
100个用户,之前7天,判断是否有提交数据,如果有提交有数据,判断是否解密成功(分别存在两个表中)。如果没有提交,显示黄色;提交,未解密成功,红色;提交并解密成功,绿色,并显示对应时间。
分析:
测试过遍历所有单位,之后遍历每一天,去查询提交数据,然后在去查询解密数据。结果一个100家单位,竟然需要大概2-3分钟的时间来查询。(接收记录里面数据大约50w条,后期可能会更多),明显不合适,虽然加过缓存,但是不符合要求。
优化思路:
1. 我想用100家单位和7天同时去关联接收记录表,进行查询。也就是多条件左外连接查询。
2. 我要获取100家单位和7天的这样的表,需要100家单位和7个日期的笛卡尔积
3. 我需要一个7天日期的表,可以在存储过程中进行创建临时表。
整体思路就是这样的。
代码:
整体存储过程代码如下:
ALTER PROCEDURE [dbo].[AUTOTRANS]
@xz VARCHAR(10)='' ,
@day INT =7,
@industryCode varchar(10)=''
AS
BEGIN
SET NOCOUNT ON;
--定义一个变量:临时表,用户存储7天数据。
DECLARE @days table (date date)
DECLARE @today date = GETDATE()
--定义一个循环,用于插入之前7天的数据,从当天开始
WHILE @day >= 0
BEGIN
insert into @days
select DATEadd(dd,-@day, @today );
set @day =@day-1
END
--业务区域
SELECT D.XZ_CODE,D.UNIT_CODE,D.UNIT_NAME, CONVERT(varchar,D.RECEIVE_TIME,108) RECEIVE_TIME,
CONVERT(varchar,MAX (E.RESTORE_TIME),108) RESTORE_TIME,D.date SELECT_DATE
FROM (
SELECT A.XZ_CODE,A.UNIT_CODE,A.UNIT_NAME,MAX(C.RECEIVE_TIME) RECEIVE_TIME,B.date FROM
(SELECT XZ_CODE,UNIT_CODE,UNIT_NAME
FROM T_UNIT_AUDIT WHERE XZ_CODE = @xz AND INDUSTRY_CODE = @industryCode
) A CROSS JOIN @days B
LEFT JOIN T_FILE_RECEIVE_RECORD C ON A.UNIT_CODE = C.UNIT_CODE AND A.XZ_CODE = C.XZ_CODE
AND CONVERT(VARCHAR,B.date,23) = CONVERT(VARCHAR,C.RECEIVE_TIME,23)
GROUP BY A.XZ_CODE,A.UNIT_CODE,A.UNIT_NAME,B.date
) D LEFT JOIN T_FILE_RESTORE_RECORD E ON D.XZ_CODE = E.XZ_CODE AND D.UNIT_CODE = E.UNIT_CODE
AND CONVERT(VARCHAR,D.RECEIVE_TIME,23) = CONVERT(VARCHAR,E.RESTORE_TIME,23)
GROUP BY D.RECEIVE_TIME,D.XZ_CODE,D.UNIT_CODE,D.UNIT_NAME,D.date
END
结果测试:
目前,针对100家单位7天的数据,可以保证大约2秒内完成查询,当然这还包含了我在后期进行数据处理的时间。
写在最后:
由于项目是使用的jdbcTemplate进行的持久层操作,所以持久层操作代码附上:
public List<Map<String, Object>> autoTrans(Map<String, Object> param) {
String sql = "{call AUTOTRANS(?,?,?)} "; //调用存储过程
List<Map<String, Object>> resultList = jdbcTemplate.execute(
//定义传入参数,返回statement
(connection)->{
CallableStatement statement = connection.prepareCall(sql);
statement.setString(1,param.get("xzCode").toString());
statement.setString(2,param.get("days").toString());
statement.setString(3,param.get("industryCode").toString());
return statement;
},
//执行存储过程,拿到结果集,处理结果集。因为这里lambda表达式如果不设置参数类型会导致重复,就设置了参数类型
(CallableStatement callableStatement) -> {
List<Map<String,Object>> resultListParam =new ArrayList<>();
callableStatement.execute();
ResultSet resultSet = callableStatement.getResultSet();
while (resultSet.next()){
Map<String,Object> result = new HashMap<>();
result.put("xzCode",resultSet.getString("XZ_CODE"));
result.put("unitCode",resultSet.getString("UNIT_CODE"));
result.put("unitName",resultSet.getString("UNIT_NAME"));
result.put("receiveTime",resultSet.getString("RECEIVE_TIME"));
result.put("restoreTime",resultSet.getString("RESTORE_TIME"));
result.put("selectDate",resultSet.getDate("SELECT_DATE"));
resultListParam.add(result);
}
return resultListParam;
});
return resultList;
}
到此结束,本次查询优化完成,基本达到目标要求。
SqlServer高级特性--存储过程的更多相关文章
- mysql的高级特性-存储过程
定义: 存储例程是存储在数据库服务器中的一组sql语句,通过在查询中调用一个指定的名称来执行这些sql语句命令. 语法: DELIMITER // 声明语句结束符,用于区分; CEATE PROCED ...
- SqlServer高级特性--游标
游标 用途:在数据很多的时候,如果在java代码中进行循环之后再进行更新数据,会造成频繁的连接数据库,耗费性能,所以就可以使用到游标 作用:查询出来的集合直接在SQL中进行遍历在进行更新 DECLAR ...
- SQLServer索引的四个高级特性
一Index Building Filter索引创建时过滤 二Index Include Column索引包含列 三聚集索引Cluster Index 四VIEW INDEX视图索引 SQLSer ...
- mysql笔记04 MySQL高级特性
MySQL高级特性 1. 分区表:分区表是一种粗粒度的.简易的索引策略,适用于大数据量的过滤场景.最适合的场景是,在没有合适的索引时,对几个分区进行全表扫描,或者是只有一个分区和索引是热点,而且这个分 ...
- Redis基础、高级特性与性能调优
本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍.之后概览Redis提供的高级能力,并在部署.维护.性能调优等多个方面进行更深入的介绍和指导. ...
- Redis 基础、高级特性与性能调优
本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍.之后概览Redis提供的高级能力,并在部署.维护.性能调优等多个方面进行更深入的介绍和指导. ...
- JDBC高级特性(一)结果集,批量更新
一.ResultSet的高级特性 1 可滚动ResultSet 1)向前和向后滚动 滚动特性 在JDBC初期版本号中, ResultSet仅能向前滚动 在JDBC兴许版本号中, ResultSet默认 ...
- 干货:鲜为人用的MySQL高级特性与玩法!
上一篇文章<万字总结:学习MySQL优化原理,这一篇就够了!>文末给大家留有两个开放的问题: 有非常多的程序员在分享时都会抛出这样一个观点:尽可能不要使用存储过程,存储过程非常不容易维护, ...
- HBase高级特性、rowkey设计以及热点问题处理
在阐述HBase高级特性和热点问题处理前,首先回顾一下HBase的特点:分布式.列存储.支持实时读写.存储的数据类型都是字节数组byte[],主要用来处理结构化和半结构化数据,底层数据存储基于hdfs ...
随机推荐
- 2.1 The Object Model -- Classes and Instances(类和实例)
一.Defining Classes(定义类) 1. 定义一个新的Ember类,调用Ember.Object上的extend()方法: example:定义了一个含有say()方法的新的Person类 ...
- TabControl delphi
1.TTabControl 组件的典型用法TTabControl 组件使用起来,根本不会使程序简单化,所以不提倡使用此组件,可以用TPageControl组件代替.与多页组件不同的是,虽然Tab 组件 ...
- Web前台学习总结
前台的技术有很多种,流行的框架也是枚不胜举,在这里我们只讨论html,css,js这些基本的技术,相信大家如果掌握了这些最基本的技术,其他的技术也就会使用了. 下面是一个案例的形式来讲解上述的技术. ...
- MyBatis—mapper.xml映射配置
SQL文件映射(mapper文件),几个顶级元素的配置: mapper元素:根节点只有一个属性namespace(命名空间)作用: 1:用于区分不同的mapper,全局唯一. 2:绑定DAO接口,即面 ...
- capistranorb
远程服务器自动部署工具 https://capistranorb.com/
- python 字节字符串上的字符串操作
问题:想在字节字符串上执行普通的文本操作(比如移除,搜索和替换). 解决方案 1)字节字符串同样也支持大部分和文本字符串一样的内置操作.比如: >>> data = b'Hello ...
- python webdriver 显示等待-自动登录126邮箱,添加联系人
脚本内容:#encoding=utf-8#author-夏晓旭from selenium import webdriverimport timefrom selenium.webdriver.supp ...
- ABP官方文档翻译 0.0 ABP官方文档翻译目录
一直想学习ABP,但囿于工作比较忙,没有合适的契机,当然最重要的还是自己懒.不知不觉从毕业到参加工作七年了,没留下点儿什么,总感觉很遗憾,所以今天终于卯足劲鼓起勇气开始写博客.有些事能做的很好,但要跟 ...
- STM32时钟树
STM32的时钟系统 相较于51单片机,stm32的时钟系统可以说是非常复杂了,我们现在看下面的一张图: 上图说明了时钟的走向,是从左至右的从时钟源一步步的分配给外设时钟.需要注意的是,上图左侧一共有 ...
- linux及安全《Linux内核设计与实现》第三章——20135227黄晓妍
第三章 (由于linux不区分进程和线程,所以它们在linux中被称为task,也叫任务) 总结:本章主要包括进程以及线程的概念和定义,Linux内核如何管理每个进程,他们在内核中如何被列举,如何创建 ...