SQL Azure上的查询性能非常差
我们有S1:20 DTU 250GB SQL Azure数据库,如下表所示SQL Azure上的查询性能非常差,sql,sql-server,azure,Sql,Sql Server,Azure,我们有S1:20 DTU 250GB SQL Azure数据库,如下表所示 CREATE TABLE [dbo].[Reads] ( [ReadId] [INT] IDENTITY(1,1) NOT NULL, [LicenseNumber] [VARCHAR](50) NULL, [Name] [VARCHAR](50) NULL, [Serial] [VARCHAR](20) NULL, [FirstSeenUtc] [DATETIME] NULL,
CREATE TABLE [dbo].[Reads]
(
[ReadId] [INT] IDENTITY(1,1) NOT NULL,
[LicenseNumber] [VARCHAR](50) NULL,
[Name] [VARCHAR](50) NULL,
[Serial] [VARCHAR](20) NULL,
[FirstSeenUtc] [DATETIME] NULL,
[LastSeenUtc] [DATETIME] NULL,
[Count] [INT] NOT NULL,
[Model] [VARCHAR](100) NULL,
[Make] [VARCHAR](100) NULL,
[TimestampUtc] [DATETIME] NOT NULL,
[PortNumber] [INT] NOT NULL,
[Code] [VARCHAR](50) NULL,
[Peak] [FLOAT] NULL,
CONSTRAINT [PK_Reads]
PRIMARY KEY CLUSTERED ([ReadId] ASC)
WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
此表有8000多万行,简单查询如下
select count(1) from dbo.Reads
运行时间为1小时30分钟。通过每分钟大约添加1000行的进程,数据库上的负载可以降到最低。目前没有从这个表中读取任何内容,总体上数据库几乎没有负载
我将数据库升级到S2:50DTU,上面的查询运行了18分钟
我更新了统计数据,但帮不了什么忙。当上面的查询运行时,我运行了Brent Ozar的BlitzFirst存储过程,它说数据库正在最大化数据IO。在我的surface笔记本电脑上恢复的同一个数据库在一秒钟内返回行数。“数据库性能”选项卡没有任何建议
S2:50 DTU的成本为每月75美元,下一个选项是S3:100 DTU,每月150美元
我的计划是为我注册的每个客户创建一个数据库,但每个数据库每月150美元,我很快就会倒闭
这是SQL Azure的预期性能级别吗?这种基本查询不应该产生即时结果吗?在VM上迁移到SQL Server会更好吗
[更新2019-03-10东部时间上午11:35]
该表确实包含以下内容:
CREATE NONCLUSTERED INDEX [IX_Read_License_Code_TimeStamp] ON [dbo].[Reads]
(
[LicenseNumber] ASC,
[Code] ASC,
[TimestampUtc] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
我现在看到,一些列可以安全地更改为NOTNULL,这有助于改进
[更新:2019-03-10美国东部时间晚上8:40]
我修改了表格,使LicenseNumber和代码不为空,这花费了6个多小时。之后,计数查询在1分32秒内运行
以下查询在40秒内返回结果
select Code, LicenseNumber, TimeStampUtc from dbo.Reads Where TimestampUtc >= '2019-03-10'
删除索引并再次创建它为我做到了这一点。在此之前,即使索引完全覆盖的查询也需要几分钟的时间来执行。重新创建索引后,相同的查询将在一秒钟内运行
感谢所有对这个问题发表评论的人。我学到了新东西。尝试在
PortNumber
上放置一个索引-这是一个不可为空的INT
列,一旦该索引存在,确定表中的行数应该会快得多。如果没有这样的索引,那么确定行数基本上意味着进行一次完整的表扫描并加载所有数据;如果索引位于窄的、不可为空的列上,则只需加载和删除该索引(更少的数据)examined@marc_sReadId
上的主键约束是否会自动为该字段编制索引?@aaaaaa 123456789:是-但不会使用“单列”非聚集索引。主键自动创建聚集索引-基本上是整个数据表-而不仅仅是一个INT
列。@marc\s这很有趣。我的理解与AAAAA123456789的相同。该表确实有一个非聚集索引(我将添加到原始问题中),当我使用实际查询计划运行count查询时,它运行了30分钟,显示92%的成本是扫描IX,其余8%是聚合操作。问题是,为什么在笔记本电脑上还原的同一数据库上的同一查询会在一秒钟内返回结果?因为现有索引中的某些(或所有)列可以为空,SQL Server无法使用此索引计算行数。行的计数发生在索引的叶级-对于聚集索引,这是整个表的数据-->因此速度很慢。最好的选择是在一个单一的、狭窄的、不可为空的列上建立一个非聚集索引,如INT NOT NULL
或类似的列,该列在单个数据页上具有最多的条目,因此扫描整个索引来计算行数将是最快的