【问题标题】:How to improve the performance of my query如何提高我的查询的性能
【发布时间】:2019-01-18 12:36:16
【问题描述】:

下面的查询从Address 表中获取不同的邮政编码大约需要 4 分 42 秒。 Address 表中有 1,006,699 条记录。表的复合键是Address1, Address2, City, ZipCode

查询运行有时需要 5 秒甚至 1 毫秒。

如何提高查询的性能?

这是 SQL 查询:

 SELECT DISTINCT ZipCode FROM Address

这是表的架构:

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

我似乎无法添加执行计划的图像。

【问题讨论】:

  • 你必须使用完全相同的列作为主键,你可以先移动邮政编码。

标签: sql database-design sql-server-2014 table-index


【解决方案1】:

对于这个查询:

SELECT DISTINCT ZipCode FROM Address

您希望在ZipCode 上或至少在ZipCode 是第一列的地方建立索引:

create index idx_address_zipcode on address(zipcode);

生成的执行计划应该是对索引的扫描,这比处理原始表(并聚合以获得不同的邮政编码)要快得多。

您还可以将现有索引更改为(zipcode, city, address1, address2)。这使得索引更有用(在我看来),因为zipcodeaddress1 更有可能用于过滤。但是,该索引仅在 zipcode 上大于 1。

【讨论】:

  • 所以这将是一个非聚集索引?
  • 是的;您只能拥有一个聚集索引,而且您已经拥有它。
  • @rds80 。 . .是的。我建议您将AddressId 设置为聚集索引,以避免在修改数据时产生碎片。
  • 当我只有 AddressID 有主键时,获取所有记录的查询需要一分钟多的时间。
【解决方案2】:

为了获得最佳性能,您可以创建一个索引视图,以便实现聚合:

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

【讨论】:

  • 非常酷!我不必进行聚合,例如每个邮政编码有多少条记录。我想要实现的是 UI 上带有邮政编码的自动完成功能。
  • DISTINCT 是一个聚合(来自多个源行的单行)。即使您不使用它,也需要COUNT_BIG() 才能对视图进行索引。
【解决方案3】:

1.如果可能,将ZipCode 数据类型从nvarchar 转换为bigint
2.try group by ZipCode

 SELECT ZipCode FROM Address GROUP BY ZipCode;

【讨论】:

  • 有些邮政编码有5个数字“-”4个数字。 distinct 和 group by 之间有性能差异吗?
  • stackoverflow.com/questions/25114506/distinct-vs-group-by/… 是的,它确实检查了这个链接
  • @rds80 如果您在邮政编码中有“-”,请从客户端验证它或在服务器端使用您的代码验证它,如果在邮政编码中找到“-”,请删除。对于数据库中的值,我建议将“-”替换为 SQL 查询,或者为了安全起见,请使用代码
猜你喜欢
  • 2013-12-15
  • 2020-02-12
  • 2021-07-30
  • 1970-01-01
  • 2012-10-20
  • 2022-01-09
  • 1970-01-01
  • 2017-02-26
  • 2012-04-10
相关资源
最近更新 更多