it-swarm.com.de

Langsamere SQL Server-Leistung nach Zuweisung von mehr CPU und RAM

Wir haben SQL Server 2008 R2 (10.50.1600) auf einem virtuellen Windows 2008 R2-Server ausgeführt. Nach dem Upgrade der CPU von 1 Kern auf 4 und der RAM von 4 GB auf 10 GB) haben wir festgestellt, dass die Leistung schlechter ist.

Einige Beobachtungen, die ich sehe:

  1. Eine Abfrage, deren Ausführung <5 Sekunden gedauert hat, dauert jetzt> 200 Sekunden.
  2. Die CPU ist mit sqlservr.exe als Schuldigen auf 100 festgelegt.
  3. Eine Auswahlanzahl (*) in einer Tabelle mit 4,6 Millionen Zeilen dauerte über 90 Sekunden.
  4. Die auf dem Server ausgeführten Prozesse haben sich nicht geändert. Die einzige Änderung bestand darin, die CPU und den RAM zu erhöhen.
  5. Andere SQL-Server verfügen über eine statische Auslagerungsdatei, in der dieser Server diese selbst verwaltet.

Hat jemand dieses Problem schon einmal erlebt?

Per sp_BlitzErik bin ich gelaufen

EXEC dbo.sp_BlitzFirst @SinceStartup = 1;

Gib mir diese Ergebnisse.

(wait stats

33
Jeff

Hier ist viel los, und das meiste davon ist ziemlich breit und vage.

  1. 2008R2 RTM wurde am 21. April 2010 veröffentlicht. Es wird kein Support mehr angeboten. Sie sollten Prioritäten setzen, um das neueste Service Pack zu erhalten, das vor knapp drei Jahren veröffentlicht wurde. Auf diese Weise sind Sie abgesichert, wenn Sie auf einen seltsamen Fehler oder etwas anderes stoßen. Gehen Sie zu hier drüben , um herauszufinden, was Sie herunterladen müssen.

  2. Da Sie vCPUs (von 1 bis 4) hinzugefügt und keine Einstellungen geändert haben, können Ihre Abfragen jetzt parallel ausgeführt werden. Ich weiß, das hört sich so an, als wären sie alle schneller, aber warte!

  3. Möglicherweise haben Sie RAM hinzugefügt, aber möglicherweise haben Sie den maximalen Serverspeicher nicht geändert, damit Ihr Server davon profitieren kann.

  4. Finden Sie heraus, worauf Ihr Server wartet. Ein Open Source-Projekt, an dem ich arbeite, bietet kostenlose Skripts, mit denen Sie Ihren SQL Server messen können. Gehen Sie weiter hier drüben wenn Sie es versuchen möchten.

Sie möchten sich sp_BlitzFirst schnappen, um die Wartestatistiken Ihres Servers zu überprüfen. Sie können es auf verschiedene Arten ausführen.

Dies zeigt Ihnen, worauf Ihr Server seit dem Start gewartet hat.

EXEC dbo.sp_BlitzFirst @SinceStartup = 1;

Dies zeigt Ihnen in einem 30-Sekunden-Fenster, auf welche Abfragen gerade gewartet wird.

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

Sobald Sie herausgefunden haben, auf welche Abfragen gewartet wird (es gibt eine Menge Dinge, die über Wartestatistiken geschrieben wurden), können Sie Änderungen vornehmen, um die Dinge unter Kontrolle zu bringen.

Wenn Sie sehen, dass sie auf CXPACKET warten, bedeutet dies, dass Ihre Abfragen parallel verlaufen und sich möglicherweise gegenseitig mit Füßen treten. Wenn Sie dies treffen, sollten Sie wahrscheinlich in Betracht ziehen, den Kostenschwellenwert für Parallelität auf 50 zu erhöhen und MAXDOP möglicherweise auf 2 zu senken.

Nach diesem Schritt möchten Sie etwas wie sp_WhoIsActive oder sp_BlitzWho (letzteres befindet sich im GitHub-Repo von früher) verwenden, um mit der Erfassung von Abfrageplänen zu beginnen. Abgesehen von den Wartestatistiken sind sie eines der wichtigsten Dinge, die Sie sich ansehen können, um herauszufinden, was falsch läuft.

Vielleicht möchten Sie auch diesen Artikel von Jonathan Kehayias über VMWare Counters lesen, um in Bezug auf SQL Server auszuchecken.

Update

Wenn man die Wartestatistiken und den Jungen überprüft, sind sie komisch. Es ist definitiv etwas mit den CPUs los. Ihr Server sitzt meistens gelangweilt herum, aber wenn sich die Dinge erwärmen, werden die Dinge schlecht. Ich werde versuchen, dies leicht zu brechen.

  1. Du triffst ein Gift warten namens THREADPOOL. Sie haben nicht viel davon, aber das ist sinnvoll, weil Ihr Server nicht besonders aktiv ist. Ich werde gleich erklären, warum.

  2. Sie haben wirklich lange durchschnittliche Wartezeiten auf SOS_SCHEDULER_YIELD und CXPACKET. Sie befinden sich auf einer VM, also möchten Sie sicherstellen, dass der SQL Server Reservierungen hat oder dass die Box nicht schrecklich überzeichnet ist. Ein lauter Nachbar kann Ihren Tag hier wirklich ruinieren. Sie sollten auch sicherstellen, dass der Server/VM-Gast/VM-Host nicht im Balanced Power-Modus ausgeführt wird. Dadurch werden Ihre CPUs auf unnötig niedrige Geschwindigkeiten heruntergefahren, und sie drehen sich nicht sofort wieder auf volle Geschwindigkeit zurück.

  3. Wie binden sie sich zusammen? Mit 4 CPUs haben Sie 512 Worker-Threads. Denken Sie daran, Sie hatten die gleiche Menge mit einer einzelnen CPU, aber jetzt, da Ihre Abfragen parallel verlaufen können, können sie viel mehr Arbeitsthreads verbrauchen. In Ihrem Fall 4 Threads pro parallelem Zweig einer parallelen Abfrage.

Was läuft parallel? Höchstwahrscheinlich alles. Der Standardkostenschwellenwert für Parallelität ist 5. Diese Zahl wurde irgendwann in den späten 90ern als Standard festgelegt, wenn auf einem Desktop gearbeitet wurde, der so aussah.

(NUTS

Zugegeben, Ihre Hardware ist kleiner als die meisten Laptops, aber Sie sind dieser Sache immer noch ein Stück voraus.

Wenn viele parallele Abfragen ausgeführt werden, gehen Ihnen diese Arbeitsthreads aus. In diesem Fall warten Abfragen nur darauf, dass die Threads gestartet werden. Dort ist auch SOS_SCHEDULER_YIELD kommt herein. Abfragen treten von CPUs ab und werden für eine lange Zeit nicht wieder aktiviert. Ich sehe keine blockierenden Wartezeiten, daher sind Sie höchstwahrscheinlich nur mit Wartezeiten für Parallelität innerhalb von Abfragen vollgestopft.

Was kannst du tun?

  1. Stellen Sie sicher, dass sich nichts im Balanced Power-Modus befindet
  2. Ändern Sie MAXDOP auf 2
  3. Ändern Sie die Kostenschwelle für Parallelität auf 50
  4. Befolgen Sie den obigen Artikel von Jon K., um VM Health) zu überprüfen
  5. Verwenden Sie das Skript sp_BlitzIndex, um nach fehlenden Indexanforderungen zu suchen.

Weitere Informationen zur Fehlerbehebung finden Sie im Whitepaper, das ich für Google geschrieben habe zur Hardwaregröße in der Cloud.

Hoffe das hilft!

55
Erik Darling

Ja! Ich habe diese Art von Situation auf SQL Server-VMs in unserer Serverfarm erlebt. Sehen Sie sich die Host-CPU-Bereitschaftszeit des VM und die Zähler für den Speicherballon-Treiber an. CPU READY TIME - BLOG TEIL I und Grundlegendes zu VMware Ballooning Die Arbeit mit meinem Systemadministrator war der Schlüssel, aber nicht einfach ...

8

Eine Sache, auf die ich nicht hingewiesen habe, ist, dass das Hinzufügen von vCPUs zu einer VM) aufgrund der Zeitplanung sehr oft verlangsamt werden kann.

Die Grundidee ist, dass der Hypervisor warten muss, bis 4 physische Kerne verfügbar sind, wenn a VM 4 vCPUs hat, damit alle vCPUs geplant werden können, auch wenn 3 davon inaktiv sind .

Wenn Ihr Host nicht viele Kerne enthält und Ihre anderen Workloads ausgelastet sind, kann dies zu zusätzlichen Wartezeiten und einem erheblichen Leistungsabfall führen.

In VMware ESXi können Sie es in den erweiterten Diagrammen über CPU Ready sehen.

Hier ist einer von vielen Artikeln mit einem realen Beispiel für dieses Ereignis und wie es diagnostiziert wurde .

Das Hinzufügen von mehr RAM kann auch zu einem plötzlichen Leistungsabfall führen, wenn die Zuweisung der VM RAM RAM größer als ein NUMA-Knoten ist).

Darüber hinaus kann die Konfiguration Ihrer vCPUs (vSockets vs. vCores) tatsächlich einige Anwendungen wie SQL Server beeinflussen. Dies liegt daran, dass SQL Server selbst NUMA-fähig ist (um die gleiche Art von NUMA-überspannendem Leistungsabfall zu vermeiden) und dass VMware virtuelle NUMA-Knoten möglicherweise unterschiedlich darstellt.

Dies wird in einem Blog-Beitrag auf der VMware-eigenen Website behandelt. .


Vor diesem Hintergrund bin ich froh, dass Sie die Probleme mit Eriks Hilfe gelöst haben, aber vielleicht möchten Sie auch diese Dinge betrachten und berücksichtigen.

5
briantist

Nur eine kleine Hilfe (kann dies nicht als Kommentar posten) Wenn ich die Antwort von @ sp_BlitzErik fortsetze, habe ich einige Fragen an Pinal und Max Vernon (kann mich nicht erinnern, wo), die besagen, wie viel MAXDOP Sie verwenden sollten:

/*************************************************************************
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));
3
Racer SQL