原始sql:
更新#result表,更新warr_bal.I/O大的原因是CIS..trans_acd_bal数据量太大,
并且#result表的数据量并不大,且如果有重复的数据,sum出来的结果呈倍数增长。
CREATE TABLE #scm(
scm_no int NULL
,amt money NULL
)
INSERT INTO #scm
SELECT scm_no
,sum(isnull(gl_amt, 0))
FROM #result t
INNER JOIN CIS..trans_acd_bal ta
ON ta.gl_project = t.scm_no
WHERE ta.gl_year = @pre_year
AND ta.gl_month = @pre_month
GROUP BY scm_no
UPDATE #result
SET warr_bal = scm.amt
FROM #result t
INNER JOIN #scm scm
ON t.scm_no = scm.scm_no
循环的时候最重要的是红色的sql语句
-----------update trans_bal from CIS..trans_acd_bal begin
DECLARE @max_idn int
,@min_idn int
,@bal_amt money
,@scm_no int
SELECT @min_idn = isnull(min(idn), 0)
FROM #result
SELECT @max_idn = isnull(max(idn), 0) + 1
FROM #result
WHILE (@min_idn < @max_idn)
BEGIN
SELECT @scm_no = isnull(scm_no, 0)
,@bal_amt = warr_bal
FROM #result t
WHERE t.idn = @min_idn
IF (@bal_amt IS NULL)
BEGIN
SELECT @bal_amt = sum(gl_amt)
FROM CIS..trans_acd_bal ta
WHERE ta.gl_year = @pre_year
AND ta.gl_month = @pre_month
AND ta.gl_project = @scm_no
UPDATE #result
SET warr_bal = @bal_amt
FROM #result t
WHERE t.idn = @min_idn
OR t.scm_no = @scm_no
END
SELECT @min_idn = min(idn)
FROM #result
WHERE idn > @min_idn
END
-----------update trans_bal from CIS..trans_acd_bal end
第二个例子:
优化前sql,2个表直接inner join I/O 异常大。
journal_entry是个大表,且有索引。
SELECT b.dept_no
,max(b.dept_name) AS dept_name
FROM journal_entry a
INNER JOIN department_info b
ON a.gl_department = b.dept_no
WHERE a.gl_acct_no > 700000
GROUP BY b.dept_no
优化后i/O降低了大概只有原来1/10的I/O,
SELECT a.gl_department as dept_no
,(select max(b.dept_name) from department_info b where a.gl_department = b.dept_no) AS dept_name
FROM journal_entry a
WHERE a.gl_acct_no > 700000
GROUP BY a.gl_department
第三个例子,普通取模循环
declare @iloop int,@ibatch int
SET @iloop = 0
SELECT @ibatch = (count(*) / 200000) + 1
FROM #pay_tmp
WHILE @iloop < @ibatch
BEGIN
EXEC (
"
UPDATE #pay_tmp
SET payment = payment + pay_amt
FROM #pay_tmp a1701250030(index id_1)
INNER JOIN #temp_pay b(index id_1)
ON a1701250030.order_no = b.order_no
AND a1701250030.order_type = b.order_type
WHERE abs(isnull(a1701250030.order_no, 0)) % @ibatch = @iloop
"
)
EXEC (
"
DELETE #temp_pay
FROM #pay_tmp a1701250031(index id_1)
INNER JOIN #temp_pay b(index id_1)
ON a1701250031.order_no = b.order_no
AND a1701250031.order_type = b.order_type
WHERE abs(isnull(a1701250031.order_no, 0)) % @ibatch = @iloop
"
)
INSERT #pay_tmp(
order_type
,order_no
,payment
)
SELECT order_type
,order_no
,pay_amt
FROM #temp_pay a
WHERE abs(isnull(a.order_no, 0)) % @ibatch = @iloop
SET @iloop = @iloop + 1
END
第四个例子:old sql update 太大,为降低I/O,增加临时表。
old sql 每个都join 去sum,所以I/O 太大
UPDATE #result
SET w0 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 0
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w1 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 1
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w2 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 2
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w3 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 3
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w4 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 4
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w5 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 5
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w6 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 6
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w7 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 7
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w8 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 8
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w9 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 9
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w10 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 10
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w11 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 11
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w12 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 12
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w13 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 13
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w14 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 14
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w15 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 15
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w16 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 16
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w17 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 17
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w18 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 18
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w19 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 19
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w20 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 20
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w21 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 21
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w22 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 22
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w23 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 23
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w24 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 24
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w25 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 25
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
,w26 = (
SELECT s.reqQty
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND s.idx = 26
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
)
FROM #result r
UPDATE #result
SET forecast_total = (
SELECT sum(isnull(s.reqQty, 0))
FROM #res s
WHERE r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')
GROUP BY s.custNo
,s.group_id
,s.loc_no
,s.skuNo
,isnull(ltrim(rtrim(s.refNo)), '')
)
FROM #result r
新的sql,放入临时表,把结果计算出来后,再去update
insert into #temptable
SELECT s.custNo
,s.group_id
,s.loc_no
,s.skuNo
,isnull(ltrim(rtrim(s.refNo)), '') AS refNo
,sum(CASE
WHEN s.idx = 0
THEN s.reqQty
END) AS w0
,sum(CASE
WHEN s.idx = 1
THEN s.reqQty
END) AS w1
,sum(CASE
WHEN s.idx = 2
THEN s.reqQty
END) AS w2
,sum(CASE
WHEN s.idx = 3
THEN s.reqQty
END) AS w3
,sum(CASE
WHEN s.idx = 4
THEN s.reqQty
END) AS w4
,sum(CASE
WHEN s.idx = 5
THEN s.reqQty
END) AS w5
,sum(CASE
WHEN s.idx = 6
THEN s.reqQty
END) AS w6
,sum(CASE
WHEN s.idx = 7
THEN s.reqQty
END) AS w7
,sum(CASE
WHEN s.idx = 8
THEN s.reqQty
END) AS w8
,sum(CASE
WHEN s.idx = 9
THEN s.reqQty
END) AS w9
,sum(CASE
WHEN s.idx = 10
THEN s.reqQty
END) AS w10
,sum(CASE
WHEN s.idx = 11
THEN s.reqQty
END) AS w11
,sum(CASE
WHEN s.idx = 12
THEN s.reqQty
END) AS w12
,sum(CASE
WHEN s.idx = 13
THEN s.reqQty
END) AS w13
,sum(CASE
WHEN s.idx = 14
THEN s.reqQty
END) AS w14
,sum(CASE
WHEN s.idx = 15
THEN s.reqQty
END) AS w15
,sum(CASE
WHEN s.idx = 16
THEN s.reqQty
END) AS w16
,sum(CASE
WHEN s.idx = 17
THEN s.reqQty
END) AS w17
,sum(CASE
WHEN s.idx = 18
THEN s.reqQty
END) AS w18
,sum(CASE
WHEN s.idx = 19
THEN s.reqQty
END) AS w19
,sum(CASE
WHEN s.idx = 20
THEN s.reqQty
END) AS w20
,sum(CASE
WHEN s.idx = 21
THEN s.reqQty
END) AS w21
,sum(CASE
WHEN s.idx = 22
THEN s.reqQty
END) AS w22
,sum(CASE
WHEN s.idx = 23
THEN s.reqQty
END) AS w23
,sum(CASE
WHEN s.idx = 24
THEN s.reqQty
END) AS w24
,sum(CASE
WHEN s.idx = 25
THEN s.reqQty
END) AS w25
,sum(CASE
WHEN s.idx = 26
THEN s.reqQty
END) AS w26
,sum(s.reqQty) as wall
FROM #res s
GROUP BY s.custNo
,s.group_id
,s.loc_no
,s.skuNo
,isnull(ltrim(rtrim(s.refNo)), '')
UPDATE #result
SET w0 = s.w0
,w1 = s.w1
,w2 = s.w2
,w3 = s.w3
,w4 = s.w4
,w5 = s.w5
,w6 = s.w6
,w7 = s.w7
,w8 = s.w8
,w9 = s.w9
,w10 = s.w10
,w11 = s.w11
,w12 = s.w12
,w13 = s.w13
,w14 = s.w14
,w15 = s.w15
,w16 = s.w16
,w17 = s.w17
,w18 = s.w18
,w19 = s.w19
,w20 = s.w20
,w21 = s.w21
,w22 = s.w22
,w23 = s.w23
,w24 = s.w24
,w25 = s.w25
,w26 = s.w26
,forecast_total = s.wall
FROM #result r
INNER JOIN #temptable s
ON r.cust_no = s.custNo
AND r.group_id = s.group_id
AND r.loc_no = s.loc_no
AND r.sku_no = s.skuNo
AND isnull(ltrim(rtrim(r.ref_no)), '') = isnull(ltrim(rtrim(s.refNo)), '')