如何提高我的查询性能
How to improve the performance of my query
下面从 Address
table 获取不同邮政编码的查询大约需要 4 分 42 秒。 Address
table中有1,006,699条记录。 table 的组合键是 Address1, Address2, City, ZipCode
。
有时查询需要 5 秒到 运行 甚至 1 毫秒。
如何提高查询的性能?
这里是 SQL 查询:
SELECT DISTINCT ZipCode FROM Address
这是 table 的架构:
CREATE TABLE [dbo].[Address]
(
[AddressID] [INT] IDENTITY(1,1) NOT NULL,
[Address1] [NVARCHAR](1000) NOT NULL,
[Address2] [NVARCHAR](1000) NOT NULL,
[City] [NVARCHAR](1000) NOT NULL,
[StateCd] [NVARCHAR](2) NULL,
[ZipCode] [NVARCHAR](10) NOT NULL,
PRIMARY KEY CLUSTERED
([Address1] ASC, [Address2] ASC, [City] ASC, [ZipCode] ASC)
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Address] ADD DEFAULT ('') FOR [Address2]
GO
我似乎无法添加执行计划的图像。
对于此查询:
SELECT DISTINCT ZipCode FROM Address
您想要 ZipCode
上的索引,或者至少 ZipCode
是第一列的索引:
create index idx_address_zipcode on address(zipcode);
生成的执行计划应该是索引扫描,这比处理原始 table(并聚合以获得不同的邮政编码)要快得多。
您也可以将现有索引更改为 (zipcode, city, address1, address2)
。这使得索引更有用(在我看来),因为 zipcode
比 address1
更有可能用于过滤。但是,该索引将仅在 zipcode
.
上大于 1
为了获得最佳性能,您可以创建一个索引视图以便具体化聚合:
CREATE VIEW vw_Address_ZipCode
WITH SCHEMABINDING
AS
SELECT ZipCode, COUNT_BIG(*) AS ZipCodeCount
FROM dbo.Address
GROUP BY ZipCode;
GO
CREATE UNIQUE CLUSTERED INDEX cdx ON dbo.vw_Address_ZipCode(ZipCode);
GO
如果您使用的是企业版,优化器可以考虑索引视图而不直接引用视图:
SELECT DISTINCT ZipCode FROM Address;
在较低版本中,您需要查询视图并添加 NOEXPAND
查询提示,以便考虑优化索引:
SELECT DISTINCT ZipCode FROM dbo.vw_Address_ZipCode WITH(NOEXPAND);
有关索引视图要求,请参阅 the documentation。
1.If 可能将 ZipCode
数据类型从 nvarchar
转换为 bigint
。
2.try 按 ZipCode
分组
SELECT ZipCode FROM Address GROUP BY ZipCode;
下面从 Address
table 获取不同邮政编码的查询大约需要 4 分 42 秒。 Address
table中有1,006,699条记录。 table 的组合键是 Address1, Address2, City, ZipCode
。
有时查询需要 5 秒到 运行 甚至 1 毫秒。
如何提高查询的性能?
这里是 SQL 查询:
SELECT DISTINCT ZipCode FROM Address
这是 table 的架构:
CREATE TABLE [dbo].[Address]
(
[AddressID] [INT] IDENTITY(1,1) NOT NULL,
[Address1] [NVARCHAR](1000) NOT NULL,
[Address2] [NVARCHAR](1000) NOT NULL,
[City] [NVARCHAR](1000) NOT NULL,
[StateCd] [NVARCHAR](2) NULL,
[ZipCode] [NVARCHAR](10) NOT NULL,
PRIMARY KEY CLUSTERED
([Address1] ASC, [Address2] ASC, [City] ASC, [ZipCode] ASC)
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Address] ADD DEFAULT ('') FOR [Address2]
GO
我似乎无法添加执行计划的图像。
对于此查询:
SELECT DISTINCT ZipCode FROM Address
您想要 ZipCode
上的索引,或者至少 ZipCode
是第一列的索引:
create index idx_address_zipcode on address(zipcode);
生成的执行计划应该是索引扫描,这比处理原始 table(并聚合以获得不同的邮政编码)要快得多。
您也可以将现有索引更改为 (zipcode, city, address1, address2)
。这使得索引更有用(在我看来),因为 zipcode
比 address1
更有可能用于过滤。但是,该索引将仅在 zipcode
.
为了获得最佳性能,您可以创建一个索引视图以便具体化聚合:
CREATE VIEW vw_Address_ZipCode
WITH SCHEMABINDING
AS
SELECT ZipCode, COUNT_BIG(*) AS ZipCodeCount
FROM dbo.Address
GROUP BY ZipCode;
GO
CREATE UNIQUE CLUSTERED INDEX cdx ON dbo.vw_Address_ZipCode(ZipCode);
GO
如果您使用的是企业版,优化器可以考虑索引视图而不直接引用视图:
SELECT DISTINCT ZipCode FROM Address;
在较低版本中,您需要查询视图并添加 NOEXPAND
查询提示,以便考虑优化索引:
SELECT DISTINCT ZipCode FROM dbo.vw_Address_ZipCode WITH(NOEXPAND);
有关索引视图要求,请参阅 the documentation。
1.If 可能将 ZipCode
数据类型从 nvarchar
转换为 bigint
。
2.try 按 ZipCode
SELECT ZipCode FROM Address GROUP BY ZipCode;