我在 sql server 2019 上工作,我在选择top 5
行时遇到问题,它需要太多时间。
表上的行数Z2DataCore.parts.SourcingNotMappedParts
70 百万行。
当运行语句选择top 5
它需要太多时间超过15 minutes
。
那么如何让它更快
选择有问题的语句
SELECT top 5 GivenPartNumber_Non,vcompanyid
into #GetSupplierAndOther
FROM Z2DataCore.parts.SourcingNotMappedParts with(nolock)
Where PriorityLevel in ('A3','A4') and vcompanyid is not null and sourcetypeid=484456
group by GivenPartNumber_Non,vcompanyid
having count(distinct sourcetypeid)=2
我估计的执行计划
https://www.brentozar.com/pastetheplan/?id=r1EPmqFx5
注意:我尝试在不使用的情况下选择上面的列,select into
但仍然很慢。
示例表脚本和索引
CREATE TABLE [Parts].[SourcingNotMappedParts](
[SourcingNotMappedPartsID] [int] IDENTITY(1,1) NOT NULL,
[SearchPart] [nvarchar](200) NULL,
[GivenManufacture] [nvarchar](200) NULL,
[CompanyId] [int] NULL,
[SourceTypeID] [int] NULL,
[RevisionId] [bigint] NULL,
[ExtractionDate] [date] NULL,
[Taxonomy] [nvarchar](250) NULL,
[PartStatus] [nvarchar](50) NULL,
[Datasheet] [nvarchar](2000) NULL,
[ROHS] [nvarchar](250) NULL,
[StockId] [int] NULL,
[SourceUrl] [nvarchar](2000) NULL,
[Description] [nvarchar](2000) NULL,
[CreatedBy] [int] NULL,
[ModifiedBy] [int] NULL,
[CreatedDate] [datetime] NULL,
[ModifiedDate] [datetime] NULL,
[Comment] [nvarchar](2000) NULL,
[Reason] [nvarchar](2000) NULL,
[PartId] [int] NULL,
[GroupID] [int] NULL,
[PartStatusID] [int] NULL,
[ManufactureStatus] [int] NULL,
[EditStatus] [int] NULL,
[FamilyID] [int] NULL,
[LookupId] [int] NULL,
[ValidationReasonId] [int] NULL,
[MatchStatus] [nvarchar](200) NULL,
[GivenPartNumber_Non] [nvarchar](200) NULL,
[GivenManufacturer_Non] [nvarchar](200) NULL,
[signatureID] [int] NULL,
[VCompanyId] [int] NULL,
[PriorityLevel] [nvarchar](10) NULL,
[NotMappedCode] [int] NULL,
[PCPartStatus] [nvarchar](50) NULL,
CONSTRAINT [PK_Parts.SourcingNotMappedParts] PRIMARY KEY CLUSTERED
(
[SourcingNotMappedPartsID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [Parts].[SourcingNotMappedParts] ADD CONSTRAINT [DF_SourcingNotMappedParts_CreatedDate] DEFAULT (getdate()) FOR [CreatedDate]
GO
ALTER TABLE [Parts].[SourcingNotMappedParts] ADD CONSTRAINT [DF_SourcingNotMappedParts_ModifiedDate] DEFAULT (getdate()) FOR [ModifiedDate]
GO
ALTER TABLE [Parts].[SourcingNotMappedParts] ADD CONSTRAINT [PK_Parts.SourcingNotMappedParts] PRIMARY KEY CLUSTERED
(
[SourcingNotMappedPartsID] 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 [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_NotMapped_SourceType] ON [Parts].[SourcingNotMappedParts]
(
[SourceTypeID] ASC,
[CompanyId] 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
CREATE NONCLUSTERED INDEX [IX_NotMapped_PriorityLevel] ON [Parts].[SourcingNotMappedParts]
(
[PriorityLevel] 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
CREATE NONCLUSTERED INDEX [IX_NotMapped_NonalphaPartCompany] ON [Parts].[SourcingNotMappedParts]
(
[GivenPartNumber_Non] ASC,
[VCompanyId] 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
CREATE NONCLUSTERED INDEX [IDX_SourcingNotMappedParts_VCompanyId] ON [Parts].[SourcingNotMappedParts]
(
[VCompanyId] 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
您的问题与
TOP 5
. 你有一个GROUP BY
andHAVING
子句,这两个子句都发生在SELECT TOP
.GROUP BY
在产生减少的结果集之前,可能必须触及数千行。出于这个原因,这并不是说您将 5 行传递给 theGROUP BY
并期望它对它们采取行动。此外,您只提供了一个估计的计划。它估计将读取 522 行。但是如果没有实际的执行计划,就无法知道实际读取了多少行。
估计的计划还具有键查找,因为您没有涵盖查询中引用的所有列的索引。键查找通常不好,因为它们对每一行执行一次。在这种情况下,估计您的索引扫描将返回 522 行。对于这 522 行中的每一行,都会有一个不同的 Key Lookup。查看您当前的索引,我会考虑添加此索引,以希望在没有 Key Lookup 的情况下为您提供 Index Seek。
此外,在此之后,您应该能够删除此索引。
您似乎没有创建正确的索引。但在创建它们之前,请调查您的查询的查询计划。如果您使用 SSMS,则选择查询并按 Ctrl + L 启用查询计划。缺失的索引也会显示在查询计划中。
这是由Pinal Dave创建的查询。它显示了您可能错过创建的前 25 个索引。