Повільніша продуктивність SQL Server після виділення більше процесора та оперативної пам'яті


33

У нас SQL Server 2008 R2 (10.50.1600) працює на віртуальному сервері Windows 2008 R2. Після оновлення процесора з 1 ядра до 4 і оперативної пам’яті з 4 гб до 10 гб, ми помітили, що продуктивність гірша.

Я бачу деякі спостереження:

  1. На запит, який запустив <5 секунд, зараз триває> 200 секунд.
  2. ЦП прив'язується до 100, винуватцем sqlservr.exe.
  3. Вибір підрахунку (*) на таблиці з 4,6 мільйона рядків зайняв 90 секунд.
  4. Процеси, що працюють на сервері, не змінилися. Єдиною зміною було збільшення процесора та оперативної пам'яті.
  5. Інші сервери sql мають статичний файл підкачки, де цей сервер встановлений для самостійного управління ним.

Хтось раніше стикався з цим питанням?

За sp_BlitzErik я побіг

EXEC dbo.sp_BlitzFirst @SinceStartup = 1;

Дав мені ці результати.

статистика очікування


9
Востаннє я бачив подібне запитання щодо SE, це було тому, що хтось з'явив процесори VM та оперативну пам’ять, але хост VM насправді не мав стільки процесорів і стільки оперативної пам’яті . Тож я би це перевірив спочатку.
користувач253751

Відповіді:


55

Тут багато чого відбувається, і більшість це досить широке і розпливчасте.

  1. 2008R2 RTM вийшов 21 квітня 2010 року. Він повністю не підтримується. Ви хочете визначити пріоритет щодо останнього пакета оновлень, який вийшов близько 3 років тому. Таким чином ви будете охоплені, якщо потрапите на дивну помилку чи щось таке. Перейдіть сюди, щоб зрозуміти, що вам потрібно завантажити.

  2. Оскільки ви додали vCPU (від 1 до 4) і не змінили жодних налаштувань, ваші запити тепер можуть йти паралельно. Я знаю, що це звучить так, що всі вони будуть швидше, але зачекай!

  3. Можливо, ви додали оперативну пам’ять, але ви, можливо, не змінили максимальну пам'ять сервера, щоб ваш сервер міг цим скористатися.

  4. З’ясуйте, що чекає ваш сервер. Проект з відкритим кодом, над яким я працюю, пропонує безкоштовні сценарії, які допоможуть вам виміряти свій SQL Server. Зайдіть сюди, якщо ви хочете спробувати.

Ви хочете схопити sp_BlitzFirst, щоб перевірити статистику очікування вашого сервера. Ви можете запустити його двома способами.

Це покаже вам, що ваш сервер чекає з моменту його запуску.

EXEC dbo.sp_BlitzFirst @SinceStartup = 1;

Це покаже вам, які запити чекають зараз, протягом 30 секундного вікна.

EXEC dbo.sp_BlitzFirst @Seconds = 30, @ExpertMode = 1;

Як тільки ви зрозумієте, на які запити вас чекають (там написано багато матеріалів про статистику очікування), ви можете почати вносити зміни, щоб отримати контроль під контролем.

Якщо ви бачите, як вони чекають CXPACKET, це означає, що ваші запити йдуть паралельно і, можливо, наточують один одного. Якщо ви натиснете на це, ви, ймовірно, захочете розглянути можливість зіткнення порогу вартості для паралельності до 50, а можливо, скинути MAXDOP до 2.

Після цього кроку, коли ви хочете використовувати щось на кшталт sp_WhoIsActive або sp_BlitzWho (останній знаходиться в репортажі GitHub від попереднього), щоб почати фіксувати плани запитів. Крім статистики очікування, вони є однією з найважливіших речей, яку ви можете подивитися, щоб зрозуміти, що відбувається не так.

Ви також можете ознайомитись із цією статтею Джонатана Кехаяса про лічильники VMWare, щоб ознайомитись із сервером SQL.

Оновлення

Перегляд статистики очікування та хлопця вони дивні. З процесорами напевно щось є. Ваш сервер сидить здебільшого нудно, але коли речі нагріваються, справи стають поганими. Я спробую це легко зламати.

  1. Ви потрапляєте на отруту, чекайте, називається THREADPOOL. У вас немає тонни цього, але це має сенс, оскільки ваш сервер не дуже активний. Я поясню, чому через хвилину.

  2. Ви дійсно довго середні очікування на SOS_SCHEDULER_YIELDі CXPACKET. Ви знаходитесь у вітчизняній машині, тому ви хочете переконатися, що на SQL Server є резервації, або що вікно не надто підписане. Шумний сусід справді може зіпсувати вам день. Ви також хочете переконатися, що сервер / гость VM / хост VM не працює в режимі збалансованого живлення. Це змушує ваші процесори повертатися до зайвих низьких швидкостей, і вони не одразу повертаються до повної швидкості.

  3. Як вони зв’язуються? З 4 процесорами у вас є 512 робочих ниток. Майте на увазі, у вас була однакова кількість з одним процесором, але тепер, коли ваші запити можуть йти паралельно, вони можуть споживати ще багато робочих ниток. У вашому випадку 4 нитки на паралельну гілку паралельного запиту.

Що відбувається паралельно? Швидше за все, все. Пороговий рівень вартості для паралелізму становить 5. Цей номер був зроблений за замовчуванням десь наприкінці 90-х, працюючи на робочому столі, який виглядав приблизно так .

Горіхи

Звичайно, ваше обладнання менше, ніж у більшості ноутбуків, але ви все ще трохи попереду цього.

Коли починається безліч паралельних запитів, у вас закінчуються ці робочі потоки. Коли це трапляється, запити просто сидять навколо, чекаючи, коли теми розпочнуть. Тут також SOS_SCHEDULER_YIELDнадходить запит. Запити відключають процесори та не відновлюються надовго. Я не бачу жодних блокуючих очікувань, тож ви, швидше за все, просто набиті на паралелізм внутрішнього запиту.

Що ти можеш зробити?

  1. Переконайтесь, що в режимі збалансованої потужності нічого не знаходиться
  2. Змініть MAXDOP на 2
  3. Змініть поріг витрат на паралелізм на 50
  4. Виконайте статтю Джона К., щоб перевірити здоров'я ВМ
  5. Використовуйте скрипт, покликаний sp_BlitzIndexшукати будь-які пропущені запити на індекс.

Для більш ретельного усунення несправностей перегляньте документ, який я написав для Google, щодо розміру обладнання в хмарі.

Сподіваюся, це допомагає!


8

Так! Я відчував подібну ситуацію на vms-сервері SQL Server на нашій фермі серверів. Подивіться на готовий час хост-процесора vm та лічильники драйверів на кульку пам'яті. CPU READY TIME - БЛОГ ЧАСТИНА I і Розуміння VMware Ballooning Робота з моїм системним адміністратором була ключем, але не так просто ...


5

Одне, на що я не бачив, - це те, що додавання vCPU до VM дуже часто може уповільнити його через планування.

Основна ідея полягає в тому, що якщо в VM є 4 vCPU, то гіпервізор повинен чекати, коли будуть доступні 4 фізичні ядра, щоб можна було запланувати всі vCPU, навіть якщо 3 з них простоюють.

Якщо у вас не так багато ядер у вашому хості, а ваші інші навантаження зайняті, це може призвести до додаткового очікування та значного зниження продуктивності.

У VMware ESXi ви можете побачити його в розширених графіках через процесор готовий.

Ось одна з багатьох статей з реальним світовим прикладом того, що відбувається, і як це було діагностовано .

Додавання більшої кількості оперативної пам’яті також може спричинити раптовий спад продуктивності, якщо розподіл оперативної пам’яті VM перевищує вузол NUMA.

Крім того, конфігурація vCPU (vSockets vs. vCores) може фактично впливати на деякі програми, такі як SQL-сервер. Це пояснюється тим, що SQL-сервер знає про себе NUMA (щоб уникнути одного і того ж падіння продуктивності, пов'язаного з NUMA) і тому, що VMware може по-різному представляти віртуальні NUMA вузли.

Про це йдеться у публікації в блозі на власному сайті VMware .


Говорячи про це, я радий, що ви вирішили проблеми з допомогою Еріка, але ви, можливо, захочете поглянути і розглянути і ці речі.


3

Просто невелика допомога (не можу розмістити це як коментар) продовжуючи відповідь @ sp_BlitzErik, у мене з’явилися запити з Піналом та Максом Верноном (не можу згадати де), які говорять про те, скільки MAXDOP ви повинні використовувати:

/*************************************************************************
Author          :   Kin Shah
Purpose         :   Recommend MaxDop settings for the server instance
Tested RDBMS    :   SQL Server 2008R2

**************************************************************************/
declare @hyperthreadingRatio bit
declare @logicalCPUs int
declare @HTEnabled int
declare @physicalCPU int
declare @SOCKET int
declare @logicalCPUPerNuma int
declare @NoOfNUMA int

select @logicalCPUs = cpu_count -- [Logical CPU Count]
    ,@hyperthreadingRatio = hyperthread_ratio --  [Hyperthread Ratio]
    ,@physicalCPU = cpu_count / hyperthread_ratio -- [Physical CPU Count]
    ,@HTEnabled = case 
        when cpu_count > hyperthread_ratio
            then 1
        else 0
        end -- HTEnabled
from sys.dm_os_sys_info
option (recompile);

select @logicalCPUPerNuma = COUNT(parent_node_id) -- [NumberOfLogicalProcessorsPerNuma]
from sys.dm_os_schedulers
where [status] = 'VISIBLE ONLINE'
    and parent_node_id < 64
group by parent_node_id
option (recompile);

select @NoOfNUMA = count(distinct parent_node_id)
from sys.dm_os_schedulers -- find NO OF NUMA Nodes 
where [status] = 'VISIBLE ONLINE'
    and parent_node_id < 64

-- Report the recommendations ....
select
    --- 8 or less processors and NO HT enabled
    case 
        when @logicalCPUs < 8
            and @HTEnabled = 0
            then 'MAXDOP setting should be : ' + CAST(@logicalCPUs as varchar(3))
                --- 8 or more processors and NO HT enabled
        when @logicalCPUs >= 8
            and @HTEnabled = 0
            then 'MAXDOP setting should be : 8'
                --- 8 or more processors and HT enabled and NO NUMA
        when @logicalCPUs >= 8
            and @HTEnabled = 1
            and @NoofNUMA = 1
            then 'MaxDop setting should be : ' + CAST(@logicalCPUPerNuma / @physicalCPU as varchar(3))
                --- 8 or more processors and HT enabled and NUMA
        when @logicalCPUs >= 8
            and @HTEnabled = 1
            and @NoofNUMA > 1
            then 'MaxDop setting should be : ' + CAST(@logicalCPUPerNuma / @physicalCPU as varchar(3))
        else ''
        end as Recommendations

-------------------------------------------------- -------

--MAX VERNON 

/* 
   This will recommend a MAXDOP setting appropriate for your machine's NUMA memory
   configuration.  You will need to evaluate this setting in a non-production 
   environment before moving it to production.

   MAXDOP can be configured using:  
   EXEC sp_configure 'max degree of parallelism',X;
   RECONFIGURE

   If this instance is hosting a Sharepoint database, you MUST specify MAXDOP=1 
   (URL wrapped for readability)
   http://blogs.msdn.com/b/rcormier/archive/2012/10/25/
   you-shall-configure-your-maxdop-when-using-sharepoint-2013.aspx

   Biztalk (all versions, including 2010): 
   MAXDOP = 1 is only required on the BizTalk Message Box
   database server(s), and must not be changed; all other servers hosting other 
   BizTalk Server databases may return this value to 0 if set.
   http://support.microsoft.com/kb/899000
*/
SET NOCOUNT ON;

DECLARE @CoreCount int;
SET @CoreCount = 0;
DECLARE @NumaNodes int;

/*  see if xp_cmdshell is enabled, so we can try to use 
    PowerShell to determine the real core count
*/
DECLARE @T TABLE (
    name varchar(255)
    , minimum int
    , maximum int
    , config_value int
    , run_value int
);
INSERT INTO @T 
EXEC sp_configure 'xp_cmdshell';
DECLARE @cmdshellEnabled BIT;
SET @cmdshellEnabled = 0;
SELECT @cmdshellEnabled = 1 
FROM @T
WHERE run_value = 1;
IF @cmdshellEnabled = 1
BEGIN
    CREATE TABLE #cmdshell
    (
        txt VARCHAR(255)
    );
    INSERT INTO #cmdshell (txt)
    EXEC xp_cmdshell 'powershell -OutputFormat Text -NoLogo -Command "& {Get-WmiObject -namespace "root\CIMV2" -class Win32_Processor -Property NumberOfCores} | select NumberOfCores"';
    SELECT @CoreCount = CONVERT(INT, LTRIM(RTRIM(txt)))
    FROM #cmdshell
    WHERE ISNUMERIC(LTRIM(RTRIM(txt)))=1;
    DROP TABLE #cmdshell;
END
IF @CoreCount = 0 
BEGIN
    /* 
        Could not use PowerShell to get the corecount, use SQL Server's 
        unreliable number.  For machines with hyperthreading enabled
        this number is (typically) twice the physical core count.
    */
    SET @CoreCount = (SELECT i.cpu_count from sys.dm_os_sys_info i); 
END

SET @NumaNodes = (
    SELECT MAX(c.memory_node_id) + 1 
    FROM sys.dm_os_memory_clerks c 
    WHERE memory_node_id < 64
    );

DECLARE @MaxDOP int;

/* 3/4 of Total Cores in Machine */
SET @MaxDOP = @CoreCount * 0.75; 

/* if @MaxDOP is greater than the per NUMA node
    Core Count, set @MaxDOP = per NUMA node core count
*/
IF @MaxDOP > (@CoreCount / @NumaNodes) 
    SET @MaxDOP = (@CoreCount / @NumaNodes) * 0.75;

/*
    Reduce @MaxDOP to an even number 
*/
SET @MaxDOP = @MaxDOP - (@MaxDOP % 2);

/* Cap MAXDOP at 8, according to Microsoft */
IF @MaxDOP > 8 SET @MaxDOP = 8;

PRINT 'Suggested MAXDOP = ' + CAST(@MaxDOP as varchar(max));

Перший сценарій повертає порожній результат. Другий повертає запропоновану пропозицію, MAXDOP = 2яка відповідає тексту @sp_BlitzErik. Спасибі!
Джефф
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.