J'ai créé un compte d'essai sur Azure , et j'ai déployé ma base de données à partir de SmarterAsp
.
Lorsque j'exécute une requête pivot sur SmarterAsp\MyDatabase
, les résultats sont apparus en 2 secondes .
Cependant, l'exécution de la même requête sur Azure\MyDatabase
a pris 94 secondes .
J'utilise SQL Server 2014 Management Studio (version d'essai) pour me connecter aux serveurs et exécuter la requête.
Est-ce une différence de vitesse car mon compte est un compte d'essai?
Quelques informations liées à ma question
la requête est:
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
L'exécution de cette requête sur 3 serveurs différents m'a donné des résultats différents en termes de temps écoulé jusqu'à ce que mon tableau croisé dynamique apparaisse à l'écran:
Azure - Temps écoulé = 100,165 s
Smarterasp.net - Temps écoulé = 2,449 sec
LocalServer - Temps écoulé = 1,716 s
En ce qui concerne mon compte d'essai sur Azure, je l'ai fait avec l'objectif principal de vérifier si j'aurai une meilleure vitesse que Smarter lors de l'exécution d'une procédure stockée comme celle ci-dessus. Je choisis pour ma base de données Niveau de service - Basique, Niveau de performance - Basique (5DTU) et Max. Taille 2 Go.
Ma base de données a 16 tables, 1 table a 145284 lignes et la taille de la base de données est de 11 Mo. C'est une base de données de test pour mon application.
Mes questions sont:
Conclusions basées sur vos entrées:
J'ai testé à nouveau ma requête sur P1 et le temps écoulé était de 0,5 seconde :)
la même requête mise à jour sur SmarterASP avait un temps écoulé de 0,8 seconde.
Maintenant, c'est clair pour moi quels sont les niveaux dans Azure et à quel point il est important d'avoir une très bonne requête (j'ai même compris ce qu'est un index et son avantage/inconvénient)
Merci à tous, Lucian
C'est avant tout une question de performance. Vous avez affaire à un code peu performant de votre part et vous devez identifier le goulot d'étranglement et y remédier. Je parle des mauvaises performances 2 secondes maintenant. Suivez les instructions de Comment analyser les performances de SQL Server . Une fois que vous obtenez cette requête à exécuter localement acceptable pour une application web (moins de 5 ms), vous pouvez poser la question de la porter sur Azure SQL DB. À l'heure actuelle, votre compte d'essai ne fait que mettre en évidence les inefficacités existantes.
...
@iddepartment int
...
iddepartment='+convert(nvarchar(max),@iddepartment)+'
...
alors c'est quoi? la colonne iddepartment
est-elle un int
ou un nvarchar
? Et pourquoi utiliser (max)
?
Voici ce que vous devriez faire:
@iddepartment
dans le SQL dynamique internenvarchar(max)
. Faites correspondre les types iddepartment
et @iddertment
iddepartment
et tous les idkpi
sVoici comment paramétrer le SQL interne:
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;
Les indices de couverture sont, de loin, la solution la plus importante. Cela nécessite évidemment plus d'informations qu'ici. Lire Conception d'index y compris tous les sous-chapitres.
Comme un commentaire plus général: ce genre de requêtes convient columnstores plus que rowstore, bien que je pense que la taille des données est, fondamentalement, minuscule. Azure SQL DB prend en charge les index de colonnes columnstore pouvant être mis à jour, vous pouvez l'expérimenter en prévision d'une taille de données sérieuse. Ils nécessitent Enterprise/Development sur la boîte locale, c'est vrai.
(pdate: la question d'origine a été modifiée pour demander également comment optimiser la requête - ce qui est également une bonne question. La question d'origine était pourquoi la différence qui est le sujet de cette réponse).
Les performances des requêtes individuelles sont fortement affectées par les niveaux de performances. Je sais que la documentation implique que les niveaux concernent la charge, ce qui n'est pas strictement vrai.
Je voudrais relancer votre test avec une base de données S2 comme point de départ et partir de là.
Être abonné à un essai n'affecte pas en soi les performances, mais avec le compte gratuit, vous utilisez probablement un niveau B qui n'est pas vraiment utilisable par quelque chose de réel - certainement pas pour une requête qui prend 2 secondes pour s'exécuter localement.
Même le déplacement entre, disons, S1 et S2 montrera une différence notable dans les performances d'une requête individuelle. Si vous voulez expérimenter, n'oubliez pas que vous êtes facturé un jour pour "n'importe quelle partie d'une journée", ce qui est probablement correct pour le niveau S, mais soyez prudent lorsque vous testez le niveau P.
Pour le fond; lorsque Azure a introduit les nouveaux niveaux l'année dernière, ils ont changé le modèle d'hébergement pour SQL. Auparavant, de nombreuses bases de données s'exécutaient sur un sqlserver.exe partagé. Dans le nouveau modèle, chaque base de données obtient effectivement son propre sqlserver.exe qui s'exécute dans un sandbox à ressources limitées. C'est ainsi qu'ils contrôlent "l'utilisation des DTU" mais affectent également les performances générales.
Cela n'a rien à voir avec le fait que votre compte est en essai, c'est en raison du niveau de performance inférieur que vous avez sélectionné.
Dans d'autres services (SmarterAsp) et exécutant une instance locale, vous n'avez probablement pas de restrictions de performances plutôt que de taille.
À ce stade, il est impossible de définir ce que signifie réellement DTU/quel type de numéro de DTU est associé à un serveur SQL installé sur votre machine locale ou dans tout autre fournisseur d'hébergement.
Cependant, il existe de bonnes analyses ( https://cbailiss.wordpress.com/2014/09/16/performance-in-new-Azure-sql-database-performance-tiers/ ) effectuées concernant ceci mais rien d'officiel.