业务场景:当一个程序或多个程序一直反复调用一张表或几张表,排除高并发情况(其本身数据量巨大)为了防止表的IO 压力过大,导致查询超时无反应 等情况出现,需要对表的压力进行分流解压;很多老猿会想到用读写分离去分担压力,但要结合实际情况去用;读写分离,适用去电商类系统,对于突然的数据量蹭蹭上来之类的情况最合适;但是对于一张表或几张表的分流就是杀鸡用牛刀大材小用;此处方法学习快,使用类似场景绰绰有余。
思路:
数据卡顿:
一:优化SQL处理慢查询 (索引是否命中?条件范围是否准确?) 执行计划IO资源比
二:数据量太大,以上解决还是卡;①建立视图、②建立触发器、③建立定时执行计划。
目的:
①建立视图: 防止你的卡顿导致整个表都卡或者被锁,建立视图,为了的是不影响主表
②建立触发器:使视图表的数据自动更新同步,当主表发生改动视图也会自动改变,两个表数据同步,保持一致性。
③建立定时执行计划:方式视图数据有遗留数据,造成数据量过大,影响性能,所以要定时删除过期的数据,添加新的数据。保持数据量永远时最近,而且没有遗留残留数据。
demo步骤如下:
触发器部分百度…………
--创建视图
--EDT 出货视图表
IF EXISTS ( SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'VIEW_SHIP_DETAIL') AND OBJECTPROPERTY(id, N'IsView') = 1 )
DROP VIEW VIEW_SHIP_DETAIL; --删除视图
GO
--创建视图
CREATE VIEW dbo.VIEW_SHIP_DETAIL
AS
SELECT FACILITY ,
SITE ,
TXN_ID ,
LOT_NO ,
SALES_ORDER ,
PO_NUMBER ,
SHIP_BY ,
CUSTOMER_ID ,
PROD ,
QTY ,
OQC_INSPECT_NO ,
EXPORT_TEST_REPORT ,
SERIAL_NO ,
CUST_SN ,
SHIPPING_BOX_NO ,
STATUS ,
PACKING_NO ,
CREATOR ,
CREATE_DATE ,
MODIFIER ,
MODIFY_DATE ,
EDT_GROUP_ID
FROM dbo.W_D_SHIP_DETAIL WITH ( NOLOCK )
WHERE MODIFY_DATE >= DATEADD(MONTH, -1, GETDATE())
GO
--事务部分
--相隔一个月时间
DECLARE @MonthDate DATETIME = DATEADD(MONTH, -1, GETDATE());
--过期数据删除
IF EXISTS ( SELECT TOP ( 1 ) * FROM VIEW_SHIP_DETAIL AS V_SD WHERE MODIFY_DATE < @MonthDate )
BEGIN
DELETE VIEW_SHIP_DETAIL
WHERE MODIFY_DATE < @MonthDate;
END;
--获取最新的数据
IF OBJECT_ID('TEMPDB..#TPMET_SHIP_DETAIL') IS NOT NULL
DROP TABLE #TPMET_SHIP_DETAIL;
SELECT *
INTO #TPMET_SHIP_DETAIL
FROM dbo.W_D_SHIP_DETAIL AS SD WITH ( NOLOCK )
WHERE SD.FACILITY = 'APAT'
AND SD.SITE = 'SZ'
AND SD.MODIFY_DATE >= @MonthDate
AND NOT EXISTS ( SELECT *
FROM VIEW_SHIP_DETAIL AS V_SD
WHERE SD.FACILITY = V_SD.FACILITY
AND SD.SITE = V_SD.SITE
AND SD.TXN_ID = V_SD.TXN_ID
AND SD.LOT_NO = V_SD.LOT_NO
AND SD.SALES_ORDER = V_SD.SALES_ORDER
AND SD.OQC_INSPECT_NO = V_SD.OQC_INSPECT_NO
AND SD.EXPORT_TEST_REPORT = V_SD.EXPORT_TEST_REPORT
AND SD.SERIAL_NO = V_SD.SERIAL_NO
AND SD.CUST_SN = V_SD.CUST_SN
AND SD.PACKING_NO = V_SD.PACKING_NO
AND SD.MODIFIER = V_SD.MODIFIER
AND SD.MODIFY_DATE = V_SD.MODIFY_DATE );
--更新视图表
IF EXISTS ( SELECT TOP ( 1 ) * FROM #TPMET_SHIP_DETAIL )
BEGIN
MERGE INTO dbo.VIEW_SHIP_DETAIL T --T目标表(被操作,被更新,添加,删除)
USING ( SELECT * FROM #TPMET_SHIP_DETAIL ) S --S源表(匹配的数据源表)
ON T.FACILITY = S.FACILITY
AND T.SITE = S.SITE
AND T.TXN_ID = S.TXN_ID
AND T.LOT_NO = S.LOT_NO
AND T.SALES_ORDER = S.SALES_ORDER
AND T.OQC_INSPECT_NO = S.OQC_INSPECT_NO
AND T.SERIAL_NO = S.SERIAL_NO
AND T.CUST_SN = S.CUST_SN
AND T.PACKING_NO = S.PACKING_NO
AND T.MODIFIER = S.MODIFIER
AND T.MODIFY_DATE = S.MODIFY_DATE
--S源表与T目标表匹配时,则更新匹配的数据到T目标表中
WHEN MATCHED THEN
UPDATE SET
T.FACILITY = S.FACILITY ,
T.SITE = S.SITE ,
T.TXN_ID = S.TXN_ID ,
T.LOT_NO = S.LOT_NO ,
T.SALES_ORDER = S.SALES_ORDER ,
T.PO_NUMBER = S.PO_NUMBER ,
T.SHIP_BY = S.SHIP_BY ,
T.CUSTOMER_ID = S.CUSTOMER_ID ,
T.PROD = S.PROD ,
T.QTY = S.QTY ,
T.OQC_INSPECT_NO = S.OQC_INSPECT_NO ,
T.EXPORT_TEST_REPORT = S.EXPORT_TEST_REPORT ,
T.SERIAL_NO = S.SERIAL_NO ,
T.CUST_SN = S.CUST_SN ,
T.SHIPPING_BOX_NO = S.SHIPPING_BOX_NO ,
T.STATUS = S.STATUS ,
T.PACKING_NO = S.PACKING_NO ,
T.CREATOR = S.CREATOR ,
T.CREATE_DATE = S.CREATE_DATE ,
T.MODIFIER = S.MODIFIER ,
T.MODIFY_DATE = S.MODIFY_DATE ,
T.EDT_GROUP_ID = S.EDT_GROUP_ID
--S源表与T目标表不匹配时——则插入到目标表中;插入到表中的行是源表中目标表中没有匹配行的行
WHEN NOT MATCHED BY TARGET THEN
INSERT ( FACILITY ,
SITE ,
TXN_ID ,
LOT_NO ,
SALES_ORDER ,
PO_NUMBER ,
SHIP_BY ,
CUSTOMER_ID ,
PROD ,
QTY ,
OQC_INSPECT_NO ,
EXPORT_TEST_REPORT ,
SERIAL_NO ,
CUST_SN ,
SHIPPING_BOX_NO ,
STATUS ,
PACKING_NO ,
CREATOR ,
CREATE_DATE ,
MODIFIER ,
MODIFY_DATE ,
EDT_GROUP_ID
)
VALUES ( S.FACILITY ,
S.SITE ,
S.TXN_ID ,
S.LOT_NO ,
S.SALES_ORDER ,
S.PO_NUMBER ,
S.SHIP_BY ,
S.CUSTOMER_ID ,
S.PROD ,
S.QTY ,
S.OQC_INSPECT_NO ,
S.EXPORT_TEST_REPORT ,
S.SERIAL_NO ,
S.CUST_SN ,
S.SHIPPING_BOX_NO ,
S.STATUS ,
S.PACKING_NO ,
S.CREATOR ,
S.CREATE_DATE ,
S.MODIFIER ,
S.MODIFY_DATE ,
S.EDT_GROUP_ID
);
END;
网友评论