为什么在SQL Azure上运行查询的速度要慢得多?

时间:2015-06-27 08:34:28

标签: sql azure ssms azure-sql-database sql-server-2014

我在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。它是我的应用程序的测试数据库。

我的问题是:

  1. 我该怎么做才能优化此查询(sp)?
  2. Azure是否推荐用于小型数据库(100mb-1Gb)?我的意思是性能与成本!
  3. 基于您输入的结论:

    • 我对查询进行了建议更改,性能提高了50%以上 - 谢谢Remus
    • 我在Azure S2上测试了我的查询,更新查询的经过时间是11秒。
    • 我再次测试了我对P1的查询,经过的时间是0.5秒:)

    • SmarterASP上相同的更新查询已经过了0.8秒的时间。

    现在很清楚Azure中的层级是什么,有一个非常好的查询有多重要(我甚至理解什么是索引及其优势/劣势)

    谢谢大家, 卢西恩

3 个答案:

答案 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)

这是你应该做的:

  • 在内部动态SQL
  • 中参数化@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/),但没有正式的。