ahm*_*ary 4 index sql-server sql-server-2019 query-performance
我正在使用 SQL Server 2019,并面临一个问题,即在进行更新时,只需要 20 秒即可更新 162 行。
Update FT SET
ft.ValueName=avo.name
FROM #package FT
inner join parts.Nop_PackageAttribute PA with(nolock)
on PA.PackageID=ft.PackageID
and PA.[Key]=FT.ZfeatureId
inner join Nop_AcceptedValuesOption AVO with(nolock)
ON convert(varchar(20),AVO.AcceptedValuesOptionID)=PA.Value
where FT.AcceptedValueID is not null
Run Code Online (Sandbox Code Playgroud)
脚本示例
create table #package
(
id int PRIMARY KEY IDENTITY(1,1),
ZfeatureId INT NULL,
AcceptedValueID INT NULL,
PackageID INT NULL,
ValueName NVARCHAR(2000) default ''
)
Run Code Online (Sandbox Code Playgroud)
我在 #package 表上的索引
create nonclustered index IDX_PackageID on #package(PackageID) include (ZfeatureId,AcceptedValueID , ValueName)
create index acceptedvaluesidpackage_idx on #package(AcceptedValueID)
Run Code Online (Sandbox Code Playgroud)
包属性表
ALTER TABLE [Parts].[Nop_PackageAttribute] ADD CONSTRAINT [PK_Nop_PackageAttribute] PRIMARY KEY CLUSTERED
(
[PackageAttributeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Customer]
GO
CREATE NONCLUSTERED INDEX [_dta_index_Nop_PackageAttribute_8_578153155__K2_K1_K3_4] ON [Parts].[Nop_PackageAttribute]
(
[PackageID] ASC,
[PackageAttributeID] ASC,
[Key] ASC
)
INCLUDE ( [Value]) 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 [Customer]
CREATE NONCLUSTERED INDEX [IDX_Key] ON [Parts].[Nop_PackageAttribute]
(
[Key] 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 [Customer]
CREATE NONCLUSTERED INDEX [IDX_PakageID] ON [Parts].[Nop_PackageAttribute]
(
[PackageID] 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 [Customer]
GO
CREATE NONCLUSTERED INDEX [IX_Nop_PackageAttribute_Key] ON [Parts].[Nop_PackageAttribute]
(
[Key] ASC
)
INCLUDE ( [PackageID],
[Value]) 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 [Customer]
CREATE TABLE [Parts].[Nop_PackageAttribute](
[PackageAttributeID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[PackageID] [int] NOT NULL,
[Key] [int] NOT NULL,
[Value] [nvarchar](max) NOT NULL,
[CreatedDate] [datetime] NULL,
[CreatedBy] [int] NULL,
[ModifiedDate] [datetime] NULL,
[ModifiedBy] [int] NULL,
[DeletedDate] [datetime] NULL,
[DeletedBy] [int] NULL,
CONSTRAINT [PK_Nop_PackageAttribute] PRIMARY KEY CLUSTERED
(
[PackageAttributeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Customer]
) ON [Customer] TEXTIMAGE_ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
Nop_AcceptedValuesOption 表
ALTER TABLE [dbo].[Nop_AcceptedValuesOption] ADD CONSTRAINT [PK_Nop_AcceptedValuesOption] PRIMARY KEY CLUSTERED
(
[AcceptedValuesOptionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Customer]
GO
CREATE NONCLUSTERED COLUMNSTORE INDEX [_dta_index_Nop_AcceptedValuesOption_5_1669580986__col__] ON [dbo].[Nop_AcceptedValuesOption]
(
[AcceptedValuesOptionID],
[AcceptedValuesID],
[Name],
[DisplayOrder],
[Description],
[CreatedDate],
[CreatedBy],
[ModifiedDate],
[ModifiedBy],
[DeletedDate],
[DeletedBy],
[Is_Split],
[AcceptedValuesOption_Value],
[AcceptedValuesOption_Unit]
)WITH (DROP_EXISTING = OFF) ON [Customer]
CREATE NONCLUSTERED INDEX [_dta_index_Nop_AcceptedValuesOption_8_1074154922__K1_3] ON [dbo].[Nop_AcceptedValuesOption]
(
[AcceptedValuesOptionID] ASC
)
INCLUDE ( [Name]) 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 [Customer]
GO
CREATE NONCLUSTERED INDEX [_dta_index_Nop_AcceptedValuesOption_8_1074154922__K2_K4_1_3] ON [dbo].[Nop_AcceptedValuesOption]
(
[AcceptedValuesID] ASC,
[DisplayOrder] ASC
)
INCLUDE ( [AcceptedValuesOptionID],
[Name]) 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 [Customer]
GO
CREATE NONCLUSTERED INDEX [NonClusteredIndex-20160824-070515] ON [dbo].[Nop_AcceptedValuesOption]
(
[AcceptedValuesID] 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 [Customer]
GO
CREATE NONCLUSTERED INDEX [NonClusteredIndex-20160829-015901] ON [dbo].[Nop_AcceptedValuesOption]
(
[Name] 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 [Customer]
GO
CREATE TABLE [dbo].[Nop_AcceptedValuesOption](
[AcceptedValuesOptionID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[AcceptedValuesID] [int] NOT NULL,
[Name] [nvarchar](500) NOT NULL,
[DisplayOrder] [int] NOT NULL,
[Description] [varchar](250) NULL,
[CreatedDate] [datetime] NULL,
[CreatedBy] [int] NULL,
[ModifiedDate] [datetime] NULL,
[ModifiedBy] [int] NULL,
[DeletedDate] [datetime] NULL,
[DeletedBy] [int] NULL,
[Is_Split] [int] NULL,
[AcceptedValuesOption_Value] [float] NULL,
[AcceptedValuesOption_Unit] [nvarchar](20) NULL,
[IsDeleted] [bit] NULL,
CONSTRAINT [PK_Nop_AcceptedValuesOption] PRIMARY KEY CLUSTERED
(
[AcceptedValuesOptionID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Customer]
) ON [Customer]
GO
SET ANSI_PADDING ON
GO
ALTER TABLE [dbo].[Nop_AcceptedValuesOption] ADD CONSTRAINT [DF_IsDeleted] DEFAULT ((0)) FOR [IsDeleted]
GO
ALTER TABLE [dbo].[Nop_AcceptedValuesOption] CHECK CONSTRAINT [FK_Nop_AcceptedValuesOption_Nop_AcceptedValues]
GO
Run Code Online (Sandbox Code Playgroud)
那么,如何增强update语句更快呢?
Dav*_*oft 10
添加到 Brendan\xe2\x80\x99s 答案,交换此转换
\ninner join Nop_AcceptedValuesOption AVO with(nolock) \nON convert(varchar(20),AVO.AcceptedValuesOptionID)=PA.Value \nRun Code Online (Sandbox Code Playgroud)\n到
\ninner join Nop_AcceptedValuesOption AVO \nON AVO.AcceptedValuesOptionID = try_cast(PA.Value as int)\nRun Code Online (Sandbox Code Playgroud)\n您应该能够用 162 个索引查找替换非聚集列存储扫描。如果您没有嵌套循环计划,请尝试inner loop join。
您应该避免在子句中将函数包装在列周围WHERE。通过环绕 a CONVERT,AcceptedValuesOptionIDSQL Server 必须在表中的每一行上运行该函数,然后才能知道该值是否等于PA.Value。
话虽如此,这很可能是WHERE导致您速度缓慢的部分。
convert(varchar(20),AVO.AcceptedValuesOptionID)=PA.Value
Run Code Online (Sandbox Code Playgroud)
我看到有两件事正在发生。
查看是否有另一种方式连接到该表,其中连接两侧的列具有相同的数据类型。
另一种选择可能是更改 上的数据类型AVO.AcceptedValuesOptionID。但是,更改现有表中的数据类型是有风险的。您需要确保在此过程中不会破坏其他查询。
此外,如果您知道始终可以PA.value包含 INT 数据的特定场景,则可以考虑创建临时表并将这些行子集插入到临时表中。您可以使用该列作为 INT 数据类型创建此临时表,然后在原始联接中使用该临时表,而不是基表。