我有q查询来选择重复行的ID。如果provinceID相同且至少有一个phonenumber相同,那么我们可以确定两行是同一个。
SELECT i1.ID
FROM pigeon.dbo.Instrument i1
WHERE EXISTS(
SELECT i2.ID
FROM pigeon.dbo.Instrument i2
WHERE i2.ID != i1.ID and i2.ProvinceID = i1.ProvinceID and
(
(RTRIM(i2.PhoneNumber1) != '' and (RTRIM(i2.PhoneNumber1) = RTRIM(i1.PhoneNumber1) or RTRIM(i2.PhoneNumber1) = RTRIM(i1.PhoneNumber2) or RTRIM(i2.PhoneNumber1) = RTRIM(i1.PhoneNumber3))) or
(RTRIM(i2.PhoneNumber2) != '' and (RTRIM(i2.PhoneNumber2) = RTRIM(i1.PhoneNumber1) or RTRIM(i2.PhoneNumber2) = RTRIM(i1.PhoneNumber2) or RTRIM(i2.PhoneNumber2) = RTRIM(i1.PhoneNumber3))) or
(RTRIM(i2.PhoneNumber3) != '' and (RTRIM(i2.PhoneNumber3) = RTRIM(i1.PhoneNumber1) or RTRIM(i2.PhoneNumber3) = RTRIM(i1.PhoneNumber2) or RTRIM(i2.PhoneNumber3) = RTRIM(i1.PhoneNumber3)))
)
)
查询执行计划
虽然其他类似的查询执行得非常好,并且执行计划中没有哈希匹配。查询是
SELECT i1.ID
FROM pigeon.dbo.Instrument i1
WHERE EXISTS(
SELECT i2.ID
FROM pigeon.dbo.Instrument i2
WHERE i2.ID != i1.ID and i2.Name = i1.Name and
(
(RTRIM(i2.PhoneNumber1) != '' and (RTRIM(i2.PhoneNumber1) = RTRIM(i1.PhoneNumber1) or RTRIM(i2.PhoneNumber1) = RTRIM(i1.PhoneNumber2) or RTRIM(i2.PhoneNumber1) = RTRIM(i1.PhoneNumber3))) or
(RTRIM(i2.PhoneNumber2) != '' and (RTRIM(i2.PhoneNumber2) = RTRIM(i1.PhoneNumber1) or RTRIM(i2.PhoneNumber2) = RTRIM(i1.PhoneNumber2) or RTRIM(i2.PhoneNumber2) = RTRIM(i1.PhoneNumber3))) or
(RTRIM(i2.PhoneNumber3) != '' and (RTRIM(i2.PhoneNumber3) = RTRIM(i1.PhoneNumber1) or RTRIM(i2.PhoneNumber3) = RTRIM(i1.PhoneNumber2) or RTRIM(i2.PhoneNumber3) = RTRIM(i1.PhoneNumber3)))
)
)
执行计划是
我为where子句中包含的所有字段创建了索引。
该表定义为
CREATE TABLE [dbo].[Instrument](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](250) NOT NULL,
[Gender] [char](1) NULL,
[Birthdate] [datetime] NULL,
[PhoneNumber1] [nvarchar](50) NULL,
[PhoneNumber2] [nvarchar](50) NULL,
[PhoneNumber3] [nvarchar](50) NULL,
[Email] [nvarchar](64) NULL,
[Address] [nvarchar](250) NULL,
[IDType] [smallint] NOT NULL,
[IDNumber] [nchar](32) NULL,
[ProvinceID] [char](16) NOT NULL,
[CityID] [char](16) NOT NULL,
[Blacklist] [bit] NULL,
[BeenProject] [nvarchar](64) NULL,
[BeenCity] [nvarchar](50) NULL,
[BeenDate] [datetime] NULL,
[BeenRemark] [nvarchar](250) NULL,
[PlateType] [smallint] NOT NULL,
[PlateNumber] [nchar](16) NULL,
[Color] [nchar](16) NULL,
[Vendor] [nvarchar](64) NULL,
[ModelID] [bigint] NOT NULL,
[Version] [nvarchar](64) NULL,
[Level] [nvarchar](64) NULL,
[ModelEx] [nvarchar](250) NULL,
[Van] [nvarchar](64) NULL,
[Volume] [nvarchar](64) NULL,
[EngineNumber] [nvarchar](64) NULL,
[VINNumber] [nvarchar](64) NULL,
[ShipmentDate] [datetime] NULL,
[BoughtDate] [datetime] NULL,
[RegisteDate] [datetime] NULL,
[Remark1] [nvarchar](500) NULL,
[Remark2] [nvarchar](500) NULL,
[Remark3] [nvarchar](500) NULL,
[Remark4] [nvarchar](500) NULL,
[Remark5] [nvarchar](500) NULL,
[Referer] [nvarchar](64) NULL,
[Shared] [bit] NOT NULL,
[Counter] [smallint] NOT NULL,
[XRefID] [bigint] NULL,
[Active] [bit] NOT NULL,
[CreatedBy] [nchar](32) NOT NULL,
[CreatedAt] [datetime] NOT NULL,
[UpdatedBy] [nchar](32) NULL,
[UpdatedAt] [datetime] NULL
)
为什么他们的执行计划如此不同?与第一个查询相比,第二个查询的性能非常好。请帮助改善第一个查询的性能。