我在Azure创建了一个试用帐户,我从SmarterAsp
部署了我的数据库。
当我在SmarterAsp\MyDatabase
上运行数据透视查询时,结果显示在 2秒中。
但是,在Azure\MyDatabase
上运行相同的查询需要 94秒。
我使用SQL Server 2014 Management Studio(试用版)连接到服务器并运行查询。
速度差异是因为我的帐户是试用帐户吗?
我的问题的一些相关信息
查询是:
ALTER procedure [dbo].[Pivot_Per_Day]
@iyear int,
@imonth int,
@iddepartment int
as
declare @columnName Nvarchar(max) = ''
declare @sql Nvarchar(max) =''
select @columnName += quotename(iDay) + ','
from (
Select day(idate) as iDay
from kpivalues where year(idate)=@iyear and month(idate)=@imonth
group by idate
)x
set @columnName=left(@columnName,len(@columnName)-1)
set @sql ='
Select * from (
select kpiname, target, ivalues, convert(decimal(18,2),day(idate)) as iDay
from kpi
inner join kpivalues on kpivalues.idkpi=kpi.idkpi
inner join kpitarget on kpitarget.idkpi=kpi.idkpi
inner join departmentbscs on departmentbscs.idkpi=kpi.idkpi
where iddepartment='+convert(nvarchar(max),@iddepartment)+'
group by kpiname,target, ivalues,idate)x
pivot
(
avg(ivalues)
for iDay in (' + @columnName + ')
) p'
execute sp_executesql @sql
在3个不同的服务器上运行此查询,在我的数据透视表出现在屏幕上之前,在经过时间方面给出了不同的结果:
Azure - 经过的时间= 100.165秒
Smarterasp.net - 经过的时间= 2.449秒
LocalServer - 已用时间= 1.716秒
关于我在Azure上的试用帐户,我的主要目标是检查在运行上述存储过程时是否有比Smarter更好的速度。 我选择我的数据库服务层 - 基本,性能级别 - 基本(5DTU)和最大。大小2GB。
我的数据库有16个表,1个表有145284行,数据库大小是11mb。它是我的应用程序的测试数据库。
我的问题是:
基于您输入的结论:
我再次测试了我对P1的查询,经过的时间是0.5秒:)
SmarterASP上相同的更新查询已经过了0.8秒的时间。
现在很清楚Azure中的层级是什么,有一个非常好的查询有多重要(我甚至理解什么是索引及其优势/劣势)
谢谢大家, 卢西恩
答案 0 :(得分:13)
(更新:原始问题已更改为也询问如何优化查询 - 这也是一个很好的问题。最初的问题是为什么差异这是答案的答案。)
单个查询的性能受性能层的严重影响。我知道文档暗示层是关于加载的,这不是严格正确的。
我会以S2数据库作为起点重新运行测试并从那里开始。
进行试用订阅本身并不会影响性能,但是对于免费帐户,您可能正在使用B级别,但实际上并不是真正可用的B级别 - 当然不适用于本地运行需要2秒钟的查询。
即使在S1和S2之间移动,也会在单个查询的性能上显示出明显的差异。 如果你想进行实验,请记住你每天都要收取“一天中的任何一部分”的费用,这对于S级来说可能没问题,但在测试P级时要小心。
背景;当Azure去年推出新层时,他们改变了SQL的托管模型。过去,许多数据库都可以在共享的sqlserver.exe上运行。在新模型中,每个数据库都有效地获取自己的sqlserver.exe,该sqlserver.exe在资源受限的沙箱中运行。这就是他们控制“DTU使用”的方式,但也会影响一般性能。
答案 1 :(得分:13)
这首先是性能问题。您正在处理性能不佳的代码,您必须确定瓶颈并解决它。我现在正在谈论糟糕的 2秒表现。遵循How to analyse SQL Server performance的指导原则。一旦您将此查询执行到本地可接受的Web应用程序(少于5毫秒),您就可以询问将其移植到Azure SQL DB的问题。目前,您的试用帐户仅突出显示现有的低效率。
...
@iddepartment int
...
iddepartment='+convert(nvarchar(max),@iddepartment)+'
...
那是什么呢? iddepartment
列是int
还是nvarchar
?为什么要使用(max)
?
这是你应该做的:
@iddepartment
nvarchar(max)
转换。使iddepartment
和@iddertment
类型匹配iddepartment
和所有idkpi
s 以下是如何参数化内部SQL:
set @sql =N'
Select * from (
select kpiname, target, ivalues, convert(decimal(18,2),day(idate)) as iDay
from kpi
inner join kpivalues on kpivalues.idkpi=kpi.idkpi
inner join kpitarget on kpitarget.idkpi=kpi.idkpi
inner join departmentbscs on departmentbscs.idkpi=kpi.idkpi
where iddepartment=@iddepartment
group by kpiname,target, ivalues,idate)x
pivot
(
avg(ivalues)
for iDay in (' +@columnName + N')
) p'
execute sp_executesql @sql, N'@iddepartment INT', @iddepartment;
到目前为止,覆盖索引是最重要的修复。这显然需要比现在更多的信息。阅读Designing Indexes,包括所有子章节。
作为更一般的评论:这种查询比rowstore更适合columnstores,尽管我认为数据大小基本上很小。 Azure SQL DB支持可更新的群集列存储索引,您可以在预测严重数据大小的情况下对其进行试验。他们确实需要在本地方框上使用Enterprise / Development,这是真的。
答案 2 :(得分:2)
这与您的帐户处于试用状态无关,因为您选择的性能水平较低。
在其他服务(SmarterAsp)和运行本地实例中,您可能没有性能限制而是大小限制。
此时,无法将DTU的实际含义/与本地计算机或任何其他主机提供商中安装的Sql服务器关联的DTU号码放在一起。
然而,对此有一些很好的分析(https://cbailiss.wordpress.com/2014/09/16/performance-in-new-azure-sql-database-performance-tiers/),但没有正式的。