我在Azure上创建了一个试用帐户,并从SmarterAsp
部署了我的数据库。
当我在SmarterAsp\MyDatabase
上运行pivot查询时,结果出现在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更快的速度。我选择我的数据库服务层-基本、性能级别-Basic(5DTU)和Max。大小为2 2GB。
我的数据库有16个表,1个表有145284行,数据库大小为11mb。这是我的应用程序的测试数据库。
我的问题是:
基于您的输入的结论:
现在我很清楚Azure中的层次是什么,以及拥有一个非常好的查询有多重要(我甚至理解了什么是索引和他的优势/劣势)
谢谢你们,卢西恩
发布于 2015-06-27 18:37:07
这首先是一个性能问题。您正在处理的是性能不佳的代码,您必须找出瓶颈并解决它。我现在说的是糟糕的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
和所有all上的索引下面是如何参数化内部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,包括所有的子章节。
作为一个更一般的评论:这种类型的查询更适合columnstores而不是行存储,尽管我估计数据大小基本上很小。Azure SQL DB支持可更新的集群化列存储索引,您可以在预计会出现严重数据大小的情况下进行试验。他们确实需要在本地机器上进行企业/开发,这是真的。
发布于 2015-06-27 17:38:44
(更新:原来的问题也被更改为如何优化查询-这也是一个很好的问题。最初的问题是为什么会有差异,这就是这个答案是关于什么的)。
单个查询的性能受性能层的影响很大。我知道文档暗示这些层是关于负载的,但严格来说这并不是真的。
我将以S2数据库为起点重新运行您的测试,并从那里开始。
试用订阅本身不会影响性能,但使用免费帐户时,您可能使用的B级别对于任何真正的东西都不是真正可用的-对于一个需要2秒才能在本地运行的查询,肯定不是这样。
比方说,即使在S1和S2之间移动,也会在单个查询的性能上显示出明显的差异。如果你想进行实验,一定要记住“一天中的任何部分”都是按天收费的,这对于S级来说可能是可以的,但在测试P级时要小心。
背景;当Azure去年引入新的层时,他们改变了SQL的托管模型。过去,许多数据库会运行在一个共享的sqlserver.exe上。在新模型中,每个数据库都有效地获得了在资源受限沙箱中运行的自己的sqlserver.exe。这就是他们控制"DTU使用“的方式,但也会影响总体性能。
发布于 2015-06-28 07:54:50
这与您的帐户处于试用状态无关,而是因为您选择的性能级别较低。
在其他服务(SmarterAsp)和运行本地实例时,您可能没有性能限制,而是大小限制。
在这一点上,不可能将DTU的实际含义/哪种类型的DTU编号与安装在您的本地计算机或任何其他主机提供商中的Sql服务器相关联。
然而,关于这一点有一些很好的分析(https://cbailiss.wordpress.com/2014/09/16/performance-in-new-azure-sql-database-performance-tiers/),但没有官方的。
https://stackoverflow.com/questions/31086778
复制相似问题