Почему запуск SQL Azure выполняется намного медленнее?
Я создал пробную учетную запись на 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)[email protected] and month(idate)[email protected]
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 при запуске хранимой процедуры, такой как выше.
Я выбираю для своей базы данных Service Tier - Basic, Performance level -Basic (5DTU) и Max. Размер 2 ГБ.
Моя база данных имеет 16 таблиц, 1 таблица имеет 145284 строки, а размер базы данных - 11 МБ. Его тестовая база данных для моего приложения.
Мои вопросы:
- Что я могу сделать, чтобы оптимизировать этот запрос (sp)?
- Рекомендуется ли Azure для небольших баз данных (100mb-1Gb)? Я имею в виду производительность и стоимость!
Выводы на основе ваших входов:
- Я сделал предложенные изменения в запросе, и производительность была улучшена с более чем 50% - Спасибо Remus
- Я протестировал свой запрос на Azure S2, а время Истекшее время для обновленного запроса - 11 секунд.
-
Я снова проверил свой запрос на P1, а время Истекшее время составляло 0,5 секунды:)
-
тот же обновленный запрос на SmarterASP имел Истекшее время 0,8 секунды.
Теперь для меня ясно, что такое уровни в Azure, и как важно иметь очень хороший запрос (я даже понял, что такое индекс и его преимущество/недостаток)
Спасибо всем,
Lucian
Ответы
Ответ 1
Это, прежде всего, вопрос производительности. Вы имеете дело с плохо исполняемым кодом с вашей стороны, и вы должны определить узкое место и обратиться к нему. Сейчас я говорю о плохом 2 секунды. Следуйте рекомендациям в Как анализировать производительность SQL Server. После того, как этот запрос будет выполнен локально приемлемым для веб-приложения (менее 5 мс), вы можете задать вопрос о его переносе в Azure SQL DB. Сейчас ваша пробная учетная запись только подчеркивает существующую неэффективность.
После обновления
...
@iddepartment int
...
iddepartment='+convert(nvarchar(max),@iddepartment)+'
...
так что это? является столбцом iddepartment
a int
или nvarchar
? И зачем использовать (max)
?
Вот что вы должны сделать:
- параметризовать
@iddepartment
во внутреннем динамическом SQL
- прекратить делать
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 [email protected]
group by kpiname,target, ivalues,idate)x
pivot
(
avg(ivalues)
for iDay in (' [email protected] + N')
) p'
execute sp_executesql @sql, N'@iddepartment INT', @iddepartment;
Индексы покрытия являются, безусловно, самым важным решением. Это, очевидно, требует больше информации, чем здесь. Прочитайте Проектирование индексов, включая все подглавы.
Как более общий комментарий: подобные запросы befit columnstores больше, чем rowstore, хотя я считаю, что размер данных в основном крошечный. Azure SQL DB поддерживает обновляемые кластерные индексы столбцов, вы можете экспериментировать с ним в ожидании серьезного размера данных. Они действительно требуют Enterprise/Development в локальной коробке, правда.
Ответ 2
( Обновить: исходный вопрос был изменен, чтобы также спросить, как оптимизировать запрос, что также является хорошим вопросом. Первоначальный вопрос заключался в том, почему разница в том, что это за ответ).
Производительность отдельных запросов сильно зависит от уровней производительности. Я знаю, что документация подразумевает, что уровни имеют нагрузку, что не совсем верно.
Я бы повторно запускал ваш тест с базой данных S2 в качестве отправной точки и оттуда.
Нахождение в пробной подписке само по себе не влияет на производительность, но со свободной учетной записью вы, вероятно, используете уровень B, который на самом деле не используется ничем реальным - конечно, не для запроса, который занимает 2 секунды для локального запуска.
Даже перемещение между, скажем, S1 и S2 покажет заметную разницу в производительности отдельного запроса.
Если вы хотите экспериментировать, помните, что вы платите за день за "любую часть дня", что, вероятно, хорошо для уровня S, но будьте осторожны при тестировании уровня P.
Для фона; когда Azure представила новые уровни в прошлом году, они изменили модель хостинга для SQL. Раньше считалось, что многие базы данных будут работать на общем сервере sqlserver.exe. В новой модели каждая база данных эффективно получает свой собственный sqlserver.exe, который работает в изолированной среде с ограниченными ресурсами. Именно так они контролируют использование DTU, но также влияют на общую производительность.
Ответ 3
Это не связано с тем, что ваша учетная запись является пробной, из-за более низкого уровня производительности, который вы выбрали.
В другой службе (SmarterAsp) и запуске локального экземпляра вы, вероятно, не имеете ограничений по производительности и ограничений по размеру.
В этот момент невозможно собрать то, что на самом деле означает DTU/какой номер DTU связан с сервером Sql, установленным на вашем локальном компьютере или в любом другом хостинг-провайдере.
Однако есть хороший анализ (https://cbailiss.wordpress.com/2014/09/16/performance-in-new-azure-sql-database-performance-tiers/), сделанный относительно этого, но ничего официального.