我在让单列“varchar(5)”字段可靠地使用表搜索而不是表扫描时遇到了一些麻烦。本例中的生产表包含 2500 万行。尽管在 35 秒内扫描 2500 万行令人印象深刻,但查询应该运行得更快。
这是部分表格说明
CREATE TABLE [dbo].[Summaries_MO]
(
[SummaryId] [int] IDENTITY(1,1) NOT NULL,
[zipcode] [char](5) COLLATE Latin1_General_100_BIN2 NOT NULL,
[Golf] [bit] NULL,
[Homeowner] [bit] NULL,
[IncomeCode] [char](1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[Pets] [bit] NULL,
CONSTRAINT [Summaries_MO_primaryKey] PRIMARY KEY NONCLUSTERED HASH
(
[SummaryId]
)WITH ( BUCKET_COUNT = 33554432),
INDEX [ixZIP] NONCLUSTERED
(
[zipcode] ASC
)
)WITH ( MEMORY_OPTIMIZED = ON , DURABILITY = SCHEMA_AND_DATA )
通常,使用包括以下内容的查询访问此表:
SELECT ...
FROM SummaryTable
WHERE ixZIP IN (SELECT ZipCode FROM @ZipCodesForMO)
此查询坚持使用表扫描。例如,我尝试过 WITH (FORCESEEK),但这只会使查询失败。
当我调查了这个问题时,我也尝试过:
SELECT * FROM Summaries WHERE ZipCode IN ('xxxxx', 'xxxxx', 'xxxxx')
当我使用 64 个或更少(实际、有效)邮政编码运行此查询时,该查询使用表搜索。
但是当我给它 65 个或更多的邮政编码时,它会使用表扫描。
总而言之,生产查询总是使用表扫描,当我指定 65 个或更多邮政编码时,查询也使用表扫描。
坦率地说,我想知道索引列的数据类型(Latin1_General_100_BIN2 NOT NULL)是否存在某种问题。我可能会尝试将邮政编码转换为整数,看看会发生什么。
但我宁愿知道发生了什么,也不愿简单地随机尝试。