我有一个使用 Azure SQL 为 Azure 云服务开发的 Web 应用程序。我从一个数据库开始,使用 JMeter,从同一个 Azure 数据中心的专用虚拟机运行负载测试。测试计划设置为仅测试一个页面,并且仅发布到该页面(忽略初始获取请求)。
我的目标是确定应用程序每秒可以处理的最大数据库事务数。使用此测试计划,我的第一系列测试平均达到 300 个请求/秒。
有问题的页面正在访问下表:
create table [dbo].[Entries]
(
[Id] int not null identity(1,1)
/* other columns here, about 10 in total */
);
alter table [dbo].[Entries] add constraint [PK_Entries] primary key ([Id]);
alter table [dbo].[Entries] add constraint [DF_Entries_Created] default(getutcdate()) for [Created];
create index [IX_Entries_EmailAddress] on [dbo].[Entries] ([EmailAddress]);
create index [IX_Entries_NACSZ] on [dbo].[Entries]
(
[FirstName]
,[LastName]
,[Address1]
,[City]
,[State]
,[Postal]
);
该页面仅执行两个查询:
select 1 where exists
(
select 1 from Entries
where EmailAddress = @EmailAddress
or (
FirstName = @FirstNAme
and LastName = @LastName
and Address1 = @Address1
and City = @City
and State = @State
and Postal = @Postal
)
);
和
insert into Entries
(
...
)
values
(
...
);
select cast(scope_identity() as int);
在我的机器(四核、8GB 内存、本地 SQL 2012 快速安装)上进行的性能测试产生了高达 800 个请求/秒,所以我很震惊地看到 Azure 服务器上的大约 300 个请求/秒的峰值。我将此归结为数据库服务器上的资源争用,并添加了必要的代码来支持分片。分片机制在其中一个关键字段上使用一致的哈希来确定要使用的连接字符串(目前可能有 3 个)。此处的目标是将数据库负载分散到 3 个 Azure SQL 数据库中,并提高应用程序的并发系数。
我已经验证了分片机制是否有效(每个数据库中的条目数量大致相等)并且已经从页面中剥离了所有非必要代码,因此所发生的只是上面提到的两个查询。我在事务上使用默认的隔离级别(读提交)。最终代码如下所示:
using (var db = ConnectToShard(keyToHash))
using (var tx = db.BeginTransaction(IsolationLevel.ReadCommitted))
{
// execute query 1
// if result from query 1 is null,
// execute query 2
tx.Commit();
}
但是,即使有所有这些额外的工作,我似乎也无法将请求/秒推到 ~500 左右。我的理想目标是 1000。我想我在 Azure SQL 性能方面遗漏了一些东西,但我不确定是什么。对改进请求/秒有什么想法或建议吗?