SqlServer高级特性--存储过程
需求:
用戶需要提交加密數(shù)據(jù),提交之后需要解密還原,還原有兩種結(jié)果:成功和失敗!
100個(gè)用戶,之前7天,判斷是否有提交數(shù)據(jù),如果有提交有數(shù)據(jù),判斷是否解密成功(分別存在兩個(gè)表中)。如果沒有提交,顯示黃色;提交,未解密成功,紅色;提交并解密成功,綠色,并顯示對(duì)應(yīng)時(shí)間。
分析:
測(cè)試過遍歷所有單位,之后遍歷每一天,去查詢提交數(shù)據(jù),然后在去查詢解密數(shù)據(jù)。結(jié)果一個(gè)100家單位,竟然需要大概2-3分鐘的時(shí)間來查詢。(接收記錄里面數(shù)據(jù)大約50w條,后期可能會(huì)更多),明顯不合適,雖然加過緩存,但是不符合要求。
優(yōu)化思路:
1. 我想用100家單位和7天同時(shí)去關(guān)聯(lián)接收記錄表,進(jìn)行查詢。也就是多條件左外連接查詢。
2. 我要獲取100家單位和7天的這樣的表,需要100家單位和7個(gè)日期的笛卡爾積
3. 我需要一個(gè)7天日期的表,可以在存儲(chǔ)過程中進(jìn)行創(chuàng)建臨時(shí)表。
整體思路就是這樣的。
代碼:
整體存儲(chǔ)過程代碼如下:
ALTER PROCEDURE [dbo].[AUTOTRANS]@xz VARCHAR(10)='410000' ,@day INT =7,@industryCode varchar(10)='6001' AS BEGINSET NOCOUNT ON;--定義一個(gè)變量:臨時(shí)表,用戶存儲(chǔ)7天數(shù)據(jù)。DECLARE @days table (date date) DECLARE @today date = GETDATE()--定義一個(gè)循環(huán),用于插入之前7天的數(shù)據(jù),從當(dāng)天開始WHILE @day >= 0BEGINinsert into @daysselect DATEadd(dd,-@day, @today );set @day =@day-1 END--業(yè)務(wù)區(qū)域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_DATEFROM (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_NAMEFROM T_UNIT_AUDIT WHERE XZ_CODE = @xz AND INDUSTRY_CODE = @industryCode) A CROSS JOIN @days BLEFT 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?結(jié)果測(cè)試:
目前,針對(duì)100家單位7天的數(shù)據(jù),可以保證大約2秒內(nèi)完成查詢,當(dāng)然這還包含了我在后期進(jìn)行數(shù)據(jù)處理的時(shí)間。
寫在最后:
由于項(xiàng)目是使用的jdbcTemplate進(jìn)行的持久層操作,所以持久層操作代碼附上:
public List<Map<String, Object>> autoTrans(Map<String, Object> param) {String sql = "{call AUTOTRANS(?,?,?)} "; //調(diào)用存儲(chǔ)過程List<Map<String, Object>> resultList = jdbcTemplate.execute(//定義傳入?yún)?shù),返回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;},//執(zhí)行存儲(chǔ)過程,拿到結(jié)果集,處理結(jié)果集。因?yàn)檫@里lambda表達(dá)式如果不設(shè)置參數(shù)類型會(huì)導(dǎo)致重復(fù),就設(shè)置了參數(shù)類型(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;}
到此結(jié)束,本次查詢優(yōu)化完成,基本達(dá)到目標(biāo)要求。
轉(zhuǎn)載于:https://www.cnblogs.com/chenmc/p/9449712.html
總結(jié)
以上是生活随笔為你收集整理的SqlServer高级特性--存储过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快速开始
- 下一篇: Laravel 引入自定义类库或第三方类