我在sql server 2012上运行以下更新命令。
update a
set a.proc_flag='CC'
from abc.dbo.table1 a with (NOLOCK)
inner join xyz.dbo.table2 b with (NOLOCK)
on a.id = b.id
where a.proc_flag ='C'
and b.dt >= dateadd(D,-(180),cast(GETDATE() as date))
and b.position in
(
'AD',
'BUE',
'DS',
'HP',
'IFER',
'MER',
'NT',
'NNG',
'TON',
'GNUM',
'ERNA',
'BL',
'DPO',
'DEM',
'HU',
'ILL',
'IKT',
'LB',
'OM',
'GE',
'RF',
'sd',
'avb');
table1包含大约1百万的记录,而table2包含数百万(大表)。 每次运行查询时,它都会从 dm_exec_requests 等待类型显示 cxpacket 进入暂停模式,所以我使用 maxdop 1 暗示不使用并行性。
之后我得到 PAGEIOLATCH_SH 等待类型。我打开活动监视器,看看那里发生了什么。所以它显示我的缓冲存储器已满13 GB(我机器的RAM仅为15 GB)。
所以请告诉我,我是否必须优化查询,否则我需要其他东西。
编辑:table2上的索引
1- CREATE NONCLUSTERED INDEX [IDX_DT] ON [dbo].[table2]
(
[dt] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
2 - CREATE NONCLUSTERED INDEX [IDX_SERVER_DT] ON [dbo].[table2]
(
[server_id] ASC,
[dt] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
表1上的索引
CREATE NONCLUSTERED INDEX [ID] ON [dbo].[table1]
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
编辑2:
这是我在查询执行计划中得到的:
StmtText StmtId NodeId Parent PhysicalOp LogicalOp Argument DefinedValues EstimateRows EstimateIO EstimateCPU AvgRowSize TotalSubtreeCost OutputList Warnings Type Parallel EstimateExecutions
update a
set a.proc_flag='CF'
from abc.dbo.table1 a with (NOLOCK)
inner join xyz.dbo.table2 b with (NOLOCK)
on a.id = b.id
where a.proc_flag ='C'
and b.dt >= dateadd(D,-(cast('180' as int)),cast(GETDATE() as date))
and b.position in
(
'ADC',
'BUSINE',
'DNC',
'HUNGUP',
'INXFER',
'MNXFER',
'NCOMIT',
'NONENG',
'TRITON',
'WRGNUM',
'XFERNA',
'BL',
'DISPO',
'DONEM',
'HU',
'INCALL',
'INKT',
'LB',
'NONCOM',
'PLEDGE',
'REF',
'SALE',
'XFER') 1 1 0 NULL NULL 1 NULL 1 NULL NULL NULL 0.03451508 NULL NULL UPDATE 0 NULL
|--Table Update(OBJECT:([abc].[dbo].[table1] AS [a]), SET:([abc].[dbo].[table1].[proc_flag] as [a].[proc_flag] = [Expr1006])) 1 2 1 Table Update Update OBJECT:([abc].[dbo].[table1] AS [a]), SET:([abc].[dbo].[table1].[proc_flag] as [a].[proc_flag] = [Expr1006]) NULL 1 0.01 1E-06 9 0.03451508 NULL NULL PLAN_ROW 0 1
|--Compute Scalar(DEFINE:([Expr1006]='CF')) 1 3 2 Compute Scalar Compute Scalar DEFINE:([Expr1006]='CF') [Expr1006]='CF' 1 0 1E-07 20 0.02451408 [Bmk1000], [Expr1006] NULL PLAN_ROW 0 1
|--Top(ROWCOUNT est 0) 1 4 3 Top Top TOP EXPRESSION:((0)) NULL 1 0 1E-07 15 0.02451398 [Bmk1000] NULL PLAN_ROW 0 1
|--Sort(DISTINCT ORDER BY:([Bmk1000] ASC)) 1 5 4 Sort Distinct Sort DISTINCT ORDER BY:([Bmk1000] ASC) NULL 1 0.01126126 0.000100015 15 0.02451388 [Bmk1000] NULL PLAN_ROW 0 1
|--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000])) 1 6 5 Nested Loops Inner Join OUTER REFERENCES:([Bmk1000]) NULL 1 0 4.18E-06 20 0.01315212 [Bmk1000] NULL PLAN_ROW 0 1
|--Nested Loops(Inner Join, OUTER REFERENCES:([b].[id])) 1 7 6 Nested Loops Inner Join OUTER REFERENCES:([b].[id]) NULL 1 0 4.18E-06 15 0.00986484 [Bmk1000] NULL PLAN_ROW 0 1
| |--Filter(WHERE:([xyz].[dbo].[table2].[position] as [b].[position]='ADC' OR [xyz].[dbo].[table2].[position] as [b].[position]='BL' OR [xyz].[dbo].[table2].[position] as [b].[position]='BUSINE' OR [xyz].[dbo].[table2].[position] as [b].[position]='DISPO' OR [xyz].[dbo].[table2].[position] as [b].[position]='DNC' OR [xyz].[dbo].[table2].[position] as [b].[position]='DONEM' OR [xyz].[dbo].[table2].[position] as [b].[position]='HU' OR [xyz].[dbo].[table2].[position] as [b].[position]='HUNGUP' OR [xyz].[dbo].[table2].[position] as [b].[position]='INCALL' OR [xyz].[dbo].[table2].[position] as [b].[position]='INKT' OR [xyz].[dbo].[table2].[position] as [b].[position]='INXFER' OR [xyz].[dbo].[table2].[position] as [b].[position]='LB' OR [xyz].[dbo].[table2].[position] as [b].[position]='MNXFER' OR [xyz].[dbo].[table2].[position] as [b].[position]='NCOMIT' OR [xyz].[dbo].[table2].[position] as [b].[position]='NONCOM' OR [xyz].[dbo].[table2].[position] as [b].[position]='NONENG' OR [xyz].[dbo].[table2].[position] as [b].[position]='PLEDGE' OR [xyz].[dbo].[table2].[position] as [b].[position]='REF' OR [xyz].[dbo].[table2].[position] as [b].[position]='SALE' OR [xyz].[dbo].[table2].[position] as [b].[position]='TRITON' OR [xyz].[dbo].[table2].[position] as [b].[position]='WRGNUM' OR [xyz].[dbo].[table2].[position] as [b].[position]='XFER' OR [xyz].[dbo].[table2].[position] as [b].[position]='XFERNA')) 1 8 7 Filter Filter WHERE:([xyz].[dbo].[table2].[position] as [b].[position]='ADC' OR [xyz].[dbo].[table2].[position] as [b].[position]='BL' OR [xyz].[dbo].[table2].[position] as [b].[position]='BUSINE' OR [xyz].[dbo].[table2].[position] as [b].[position]='DISPO' OR [xyz].[dbo].[table2].[position] as [b].[position]='DNC' OR [xyz].[dbo].[table2].[position] as [b].[position]='DONEM' OR [xyz].[dbo].[table2].[position] as [b].[position]='HU' OR [xyz].[dbo].[table2].[position] as [b].[position]='HUNGUP' OR [xyz].[dbo].[table2].[position] as [b].[position]='INCALL' OR [xyz].[dbo].[table2].[position] as [b].[position]='INKT' OR [xyz].[dbo].[table2].[position] as [b].[position]='INXFER' OR [xyz].[dbo].[table2].[position] as [b].[position]='LB' OR [xyz].[dbo].[table2].[position] as [b].[position]='MNXFER' OR [xyz].[dbo].[table2].[position] as [b].[position]='NCOMIT' OR [xyz].[dbo].[table2].[position] as [b].[position]='NONCOM' OR [xyz].[dbo].[table2].[position] as [b].[position]='NONENG' OR [xyz].[dbo].[table2].[position] as [b].[position]='PLEDGE' OR [xyz].[dbo].[table2].[position] as [b].[position]='REF' OR [xyz].[dbo].[table2].[position] as [b].[position]='SALE' OR [xyz].[dbo].[table2].[position] as [b].[position]='TRITON' OR [xyz].[dbo].[table2].[position] as [b].[position]='WRGNUM' OR [xyz].[dbo].[table2].[position] as [b].[position]='XFER' OR [xyz].[dbo].[table2].[position] as [b].[position]='XFERNA') NULL 1 0 7.18E-06 20 0.00657756 [b].[id] NULL PLAN_ROW 0 1
| | |--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1003]) OPTIMIZED) 1 9 8 Nested Loops Inner Join OUTER REFERENCES:([Bmk1003]) OPTIMIZED NULL 1 0 4.18E-06 24 0.00657038 [b].[id], [b].[position] NULL PLAN_ROW 0 1
| | |--Compute Scalar(DEFINE:([Expr1018]=BmkToPage([Bmk1003]))) 1 11 9 Compute Scalar Compute Scalar DEFINE:([Expr1018]=BmkToPage([Bmk1003])) [Expr1018]=BmkToPage([Bmk1003]) 1 0.003125 0.0001581 15 0.0032831 [Bmk1003], [Expr1018] NULL PLAN_ROW 0 1
| | | |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1016], [Expr1017], [Expr1015])) 1 12 11 Nested Loops Inner Join OUTER REFERENCES:([Expr1016], [Expr1017], [Expr1015]) NULL 1 0.003125 0.0001581 15 0.0032831 [Bmk1003] NULL PLAN_ROW 0 1
| | | |--Compute Scalar(DEFINE:(([Expr1016],[Expr1017],[Expr1015])=GetRangeWithMismatchedTypes(dateadd(day,(-180),CONVERT(date,getdate(),0)),NULL,(22)))) 1 13 12 Compute Scalar Compute Scalar DEFINE:(([Expr1016],[Expr1017],[Expr1015])=GetRangeWithMismatchedTypes(dateadd(day,(-180),CONVERT(date,getdate(),0)),NULL,(22))) ([Expr1016],[Expr1017],[Expr1015])=GetRangeWithMismatchedTypes(dateadd(day,(-180),CONVERT(date,getdate(),0)),NULL,(22)) 1 0 0 27 0 [Expr1016], [Expr1017], [Expr1015] NULL PLAN_ROW 0 1
| | | | |--Constant Scan 1 14 13 Constant Scan Constant Scan NULL NULL 1 0 0 0 0 NULL NULL PLAN_ROW 0 1
| | | |--Index Seek(OBJECT:([xyz].[dbo].[table2].[IDX_DTANSWERED] AS [b]), SEEK:([b].[dt] > [Expr1016] AND [b].[dt] < [Expr1017]) ORDERED FORWARD) 1 18 12 Index Seek Index Seek OBJECT:([xyz].[dbo].[table2].[IDX_DTANSWERED] AS [b]), SEEK:([b].[dt] > [Expr1016] AND [b].[dt] < [Expr1017]) ORDERED FORWARD [Bmk1003] 1 0.003125 0.0001581 15 0.0032831 [Bmk1003] NULL PLAN_ROW 0 1
| | |--RID Lookup(OBJECT:([xyz].[dbo].[table2] AS [b]), SEEK:([Bmk1003]=[Bmk1003]) LOOKUP ORDERED FORWARD) 1 23 9 RID Lookup RID Lookup OBJECT:([xyz].[dbo].[table2] AS [b]), SEEK:([Bmk1003]=[Bmk1003]) LOOKUP ORDERED FORWARD [b].[id], [b].[position] 1 0.003125 0.0001581 28 0.0032831 [b].[id], [b].[position] NULL PLAN_ROW 0 1
| |--Index Seek(OBJECT:([abc].[dbo].[table1].[IDX_PHONE] AS [a]), SEEK:([a].[id]=[xyz].[dbo].[table2].[id] as [b].[id]) ORDERED FORWARD) 1 30 7 Index Seek Index Seek OBJECT:([abc].[dbo].[table1].[IDX_PHONE] AS [a]), SEEK:([a].[id]=[xyz].[dbo].[table2].[id] as [b].[id]) ORDERED FORWARD [Bmk1000] 1 0.003125 0.0001581 15 0.0032831 [Bmk1000] NULL PLAN_ROW 0 1
|--RID Lookup(OBJECT:([abc].[dbo].[table1] AS [a]), SEEK:([Bmk1000]=[Bmk1000]), WHERE:([abc].[dbo].[table1].[proc_flag] as [a].[proc_flag]='C') LOOKUP ORDERED FORWARD) 1 32 6 RID Lookup RID Lookup OBJECT:([abc].[dbo].[table1] AS [a]), SEEK:([Bmk1000]=[Bmk1000]), WHERE:([abc].[dbo].[table1].[proc_flag] as [a].[proc_flag]='C') LOOKUP ORDERED FORWARD NULL 1 0.003125 0.0001581 12 0.0032831 NULL NULL PLAN_ROW 0 1
修改:3
在进行大量搜索后,我还要添加一件事。我发现一些查询给了我以下输出,为什么上面的查询进入暂停模式,因为 pageiolatch_sh
Object Type Index Index_Type buffer_pages buffer_mb
TABLE2 USER_TABLE HEAP 1319249 10306
答案 0 :(得分:0)
您没有告诉我们该查询是否在合理的时间跨度内完成
如果是这种情况,那么你不应该修改它(阅读关于premature optimization ^^的许多文章之一)。
第一个改进是表2中的index on the foreign key;处理数百万行,其中一个链接字段未编入索引。你评估了这样一个索引对你的申请的影响吗?是否可以在系统上创建该索引而不影响日常操作?
根据应用的WHERE
过滤器产生的行数,您可以尝试使用子查询:
update a
set a.proc_flag='CC'
from abc.dbo.table1 a with (NOLOCK)
inner join (
select [only the fields you need] from xyz.dbo.table2
dt >= dateadd(D,-(180),cast(GETDATE() as date))
and position in ('AD',...,'avb')
) b on a.id = b.id
where a.proc_flag ='C';
如果过滤器大大减少了table2的行数,这个解决方案可能会有所改进
对于table1也是如此;如果proc_flag
上的过滤器排除将过滤器移动到子查询中的一半行可能会有一些改进
以上只是猜测,因为query optimizer,但变化是如此之小,可能值得一试...