我在SQL Server 2008中有这样的功能,执行时间那么长。
CREATE TABLE [dbo].[T_SourcePayin](
[sourcePayinId] [int] IDENTITY(1,1) NOT NULL,
[checkPeriod] [varchar](6) NOT NULL,
[kdDeptId] [varchar](20) NOT NULL,
[zxDeptId] [varchar](20) NOT NULL,
[amount] [decimal](18, 6) NOT NULL,
[processDate] [smalldatetime] NULL,
[operatorId] [varchar](20) NOT NULL,
[manual] [bit] NULL,
[disabled] [bit] NOT NULL,
[chargeTypeId] [varchar](20) NOT NULL,
[nono] [varchar](20) NULL,
[remarks] [varchar](50) NULL,
[kdDeptCode] [varchar](32) NULL,
[zxDeptCode] [varchar](32) NULL,
[hlDeptCode] [varchar](10) NULL,
[cwClass] [varchar](20) NULL,
[outin] [varchar](6) NULL,
[chargeItem] [varchar](20) NULL,
[kdHsDeptId] [varchar](10) NULL,
[zxHsDeptId] [varchar](10) NULL,
[kdRatio] [decimal](8, 6) NULL,
[zxRatio] [decimal](8, 6) NULL,
[kdjjRatio] [decimal](8, 6) NULL,
[zxjjRatio] [decimal](8, 6) NULL,
[ekdRatio] [decimal](18, 6) NULL,
[ezxRatio] [decimal](18, 6) NULL,
[freemark] [varchar](50) NULL,
[freeType] [varchar](20) NULL,
[jmRatio] [decimal](18, 6) NULL,
[dfRatio] [decimal](18, 6) NULL,
[mzRatio] [decimal](18, 6) NULL,
[zyRatio] [decimal](18, 6) NULL,
[ejmRatio] [decimal](18, 6) NULL,
[edfRatio] [decimal](18, 6) NULL,
[emzRatio] [decimal](18, 6) NULL,
[ezyRatio] [decimal](18, 6) NULL,
[kdDoctor] [varchar](20) NULL,
[kdDoctorNo] [varchar](20) NULL,
[qtjjratio] [decimal](18, 6) NULL,
[hljjratio] [decimal](18, 6) NULL,
[hlDeptId] [varchar](10) NULL,
[hlhsDeptId] [varchar](10) NULL,
[qtDeptId] [varchar](10) NULL,
[qtHsDeptId] [varchar](10) NULL,
[qtratio] [decimal](18, 6) NULL,
[eqtRatio] [decimal](18, 6) NULL,
[hlratio] [decimal](18, 6) NULL,
[ehlratio] [decimal](18, 6) NULL,
[quantity] [decimal](12, 2) NULL,
[patientId] [varchar](20) NULL,
[patientName] [varchar](20) NULL,
[kdysDeptId] [varchar](10) NULL,
[zxysDeptId] [varchar](10) NULL,
[yjDeptId] [varchar](10) NULL,
[hldydeptId] [varchar](10) NULL,
[ysratio] [decimal](18, 6) NULL,
[kdysratio] [decimal](18, 6) NULL,
[zxysratio] [decimal](18, 6) NULL,
[yjratio] [decimal](18, 6) NULL,
[hldyratio] [decimal](18, 6) NULL,
[lc] [decimal](18, 4) NULL,
[chargeitemName] [varchar](64) NULL,
[ysdeptId] [varchar](10) NULL,
[epayinRuleId] [varchar](30) NULL,
[payinRuleId] [varchar](30) NULL,
[jjpayinRuleId] [varchar](30) NULL,
CONSTRAINT [PK_T_SourcePayin] PRIMARY KEY CLUSTERED
(
[checkPeriod] ASC,
[sourcePayinId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
/****** Object: Index [IX_T_SourcePayin] Script Date: 05/21/2013 09:27:41 ******/
CREATE NONCLUSTERED INDEX [IX_T_SourcePayin] ON [dbo].[T_SourcePayin]
(
[checkPeriod] ASC,
[chargeItem] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
表 T_sourcepayin 每月有 100k 行。这是一个名为 t_mapinter 的映射表,如下约 100 行:
CREATE TABLE [dbo].[T_MapInter](
[type] [varchar](20) NULL,
[inID] [varchar](32) NULL,
[inName] [varchar](64) NULL,
[outID] [varchar](32) NULL,
[outName] [varchar](64) NULL,
[ratio] [decimal](18, 2) NULL,
[remarks] [varchar](128) NULL,
[id] [int] IDENTITY(1,1) NOT NULL,
[lastUsedTime] [datetime] NULL,
[lastUsedInter] [varchar](32) NULL
) ON [PRIMARY]
在我的项目中,我使用T_sourcepayinT
获取一个月的数据,然后插入其中,从 t_mapinter 更新大约 20 次,如下:
truncate table t_sourcepayint
--delete index
--31s or 60s
insert into t_sourcepayint
select * from t_sourcepayin where checkPeriod = '201305'
-- create index for t_sourcepayint
/****** Object: Index [idx_unc_oi_i_sid_cid] Script Date: 03/17/2013 10:03:25 ******/
CREATE NONCLUSTERED INDEX [idx_unc_oi_i_sid_cid] ON [dbo].[t_sourcepayint]
(
[outin] ASC
)
INCLUDE ( [sourcePayinId],
[chargeItem]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
/****** Object: Index [IX_t_sourcepayint] Script Date: 03/17/2013 10:03:26 ******/
CREATE NONCLUSTERED INDEX [IX_t_sourcepayint] ON [dbo].[t_sourcepayint]
(
[chargeItem] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
/****** Object: Index [IX_t_sourcepayint_kdhsdeptid] Script Date: 03/17/2013 10:03:26 ******/
CREATE NONCLUSTERED INDEX [IX_t_sourcepayint_kdhsdeptid] ON [dbo].[t_sourcepayint]
(
[kdHsDeptId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
/****** Object: Index [IX_t_sourcepayint_zxhsDeptID] Script Date: 03/17/2013 10:03:26 ******/
CREATE NONCLUSTERED INDEX [IX_t_sourcepayint_zxhsDeptID] ON [dbo].[t_sourcepayint]
(
[zxHsDeptId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
--update as follows
update a set kdhsdeptid = b.inID
from t_sourcepayint a, (select * from t_mapinter ) b
where a.kddeptid = b.outid
update a set zxhsdeptid = b.inID
from t_sourcepayint a, (select * from t_mapinter ) b
where a.zxdeptid = b.outid
-- t_chargeitem have about 10k rows
update a set kdratio = b.ratio
from t_sourcepayint a, (select chargeitem,ratio from t_chargeitem ) b
where a.kddeptid = 'D000034' and a.chargeitem = b.chargeitem
update a set kdratio = b.ratio
from t_sourcepayint a, (select chargeitem,ratio from t_chargeitem ) b
where a.kddeptid in ('D000038','D000056') and a.chargeitem = b.chargeitem
......
-- update back to t_sourcepayin about 120s
update a set kdratio = b.kdratio,zxratio = b.zxratio, kdjjratio = b.kdjjratio, ...
from t_sourcepayin a, t_sourcepayint b
where a.checkPeriod = '201305' and a.sourcepayinID = b.sourcepayinID
execut time
总和是 5 分钟。
如何提高执行效率?更改执行序列或为表 T_sourcepayinT 或 t_sourcepayin 创建更有效的索引。
update insert
可能是另一种方式?