【发布时间】:2022-01-05 18:24:13
【问题描述】:
我使用 SQL Server 并遇到查询非常慢的问题。
INSERT INTO [ExtractReports].[dbo].[TradeCodesDelete] (PartID,
Code,
CodeTypeID,
SourceTypeID,
RevisionID,
ZPLID,
PartLevel,
CreatedDate,
FlagDelete)
----select count(1) from [ExtractReports].[dbo].[TradeCodesDelete]
---update [ExtractReports].[dbo].[TradeCodesDelete] set FlagDelete=2 where FlagDelete=1
SELECT DISTINCT
FT.PartId,
TN.Code,
FT.CodeTypeID,
FT.SourceTypeID,
FT.RevisionID,
fm.[Value],
FT.PartLevel,
GETDATE(),
1
FROM Parts.Nop_Part pt WITH (NOLOCK)
INNER JOIN Parts.Nop_PartsFamilyAttribute fm WITH (NOLOCK) ON pt.PartsFamilyID = fm.PartFamilyID
AND fm.[Key] = 20281007
INNER JOIN ExtractReports.dbo.TPls pl WITH (NOLOCK) ON pl.ZPLID = fm.Value
INNER JOIN Parts.TradeCodes FT WITH (NOLOCK) ON pt.PartID = FT.PartID
AND FT.PartLevel = 0
INNER JOIN ExtractReports.dbo.TPLNewData TN WITH (NOLOCK) ON TN.PartID = FT.PartID
AND TN.CodeTypeID = FT.CodeTypeID
LEFT JOIN [ExtractReports].[dbo].[TradeCodesDelete] d ON d.partid = FT.partid
AND d.codetypeid = FT.codetypeid
AND d.partlevel = 0
WHERE TN.Code <> FT.Code
AND FT.MappingDoneFlag = 0
AND d.partid IS NULL;
由于查询性能缓慢,我检查了执行计划。
这是我的执行计划:https://www.brentozar.com/pastetheplan/?id=SJCzRrmht
- 索引搜索高达 57% - 如何降低它?
- 哈希匹配内连接高达 40% - 如何降低?
- 计算标量为 1% - 如何降低它?
谁能帮帮我?
表格脚本如下:
CREATE TABLE [Parts].[Nop_PartsFamilyAttribute]
(
[PartFamilyAttributeID] [int] IDENTITY(1,1)
NOT FOR REPLICATION NOT NULL,
[PartFamilyID] [int] NOT NULL,
[Key] [int] NOT NULL,
[Value] [nvarchar](2200) NULL,
[CreatedDate] [datetime] NULL,
[CreatedBy] [int] NULL,
[ModifiedDate] [datetime] NULL,
[Modifiedby] [int] NULL,
[DeletedDate] [datetime] NULL,
[DeletedBy] [int] NULL,
CONSTRAINT [PK_Nop_PartsFamilyAttribute30]
PRIMARY KEY CLUSTERED ([PartFamilyAttributeID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [Customer],
CONSTRAINT [UK_PartFamilyID_Key30]
UNIQUE NONCLUSTERED ([PartFamilyID] ASC, [Key] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [Customer]
) ON [Customer]
我尝试了什么:
create index pf_idx on Parts.Nop_PartsFamilyAttribute([Key]) include ([Value])
但没有任何改变 仍然是索引查找 57
和哈希匹配 40
并计算标量成本 1
那么我该怎么解决执行计划的问题?
【问题讨论】:
-
我会说从删除 NOLOCK 开始,然后看看计划如何变化。
-
为什么
[Value]是[nvarchar](2200)?在您询问的哈希连接之前,它会隐式转换为int。 (ON pl.ZPLID = fm.Value) - 可能你可以摆脱隐式转换并添加一个合适的索引以允许搜索它, -
您关心的估计只是估计,甚至更多,所以这是在您的估计执行计划中,而不是实际执行计划,因此它们甚至可能具有误导性或实际执行计划可能完全不同. 1. 查询运行需要多长时间/是否比可接受的速度慢? 2.您能否在您的问题中提供实际的执行计划(这将更有帮助建议您做什么)? 3. 不要再担心估计的百分比了。 4.不要到处使用
NOLOCK提示,这很可能对你的表现没有帮助...... -
我建议:删除
DISTINCT,这是一种代码味道,表明连接的想法很糟糕,您应该找到重复的来源,而不是盲目地使用DISTINCT。将SourceTypeID和RevisionID添加到TradeCodes索引作为INCLUDE列,避免键查找。并在UK_PartFamilyID_Key30上交换两列,这样你就得到CONSTRAINT [UK_PartFamilyID_Key30] UNIQUE NONCLUSTERED ([PartFamilyID] ASC, [Key] ASC),或者至少添加一个二级索引。同时删除类型不匹配,并将LEFT JOINIS NULL转换为WHERE NOT EXISTS
标签: sql-server stored-procedures sql-server-2012 sql-server-2017