Der Bediener hat tempdb verwendet, um Daten während der Ausführung mit Überlaufstufe 2 zu überlaufen


16

Ich habe Mühe, die Kosten für den Sortiervorgang in einem Abfrageplan mit der Warnungstempdb zu Operator usedminimierento spill data during execution with spill level 2

Ich habe mehrere Posts gefunden, die sich auf Spill-Daten während der Ausführung mit Spill-Level 1 beziehen , aber nicht mit Level 2. Level 1 scheint auf veraltete Statistiken zurückzuführen zu sein . Was ist mit Level 2? Ich konnte nichts im Zusammenhang mit findenlevel 2 .

Ich fand diesen Artikel im Zusammenhang mit Sortierungswarnungen sehr interessant:

Ignorieren Sie niemals eine Sortierwarnung in SQL Server

Mein SQL Server?

Microsoft SQL Server 2014 (SP2) (KB3171021) - 12.0.5000.0 (X64) 17. Juni 2016, 19:14:09 Uhr Copyright (c) Microsoft Corporation Enterprise Edition (64-Bit) unter Windows NT 6.3 (Build 9600:) (Hypervisor)

Meine Hardware?

Führen Sie die folgende Abfrage aus, um die Harware zu finden:

- Hardwareinformationen von SQL Server 2012

SELECT cpu_count AS [Logical CPU Count], hyperthread_ratio AS [Hyperthread Ratio],
cpu_count/hyperthread_ratio AS [Physical CPU Count], 
physical_memory_kb/1024 AS [Physical Memory (MB)], affinity_type_desc, 
virtual_machine_type_desc, sqlserver_start_time
FROM sys.dm_os_sys_info WITH (NOLOCK) OPTION (RECOMPILE);

Bildbeschreibung hier eingeben

aktuell zugewiesener Speicher

SELECT
(physical_memory_in_use_kb/1024) AS Memory_usedby_Sqlserver_MB,
(locked_page_allocations_kb/1024) AS Locked_pages_used_Sqlserver_MB,
(total_virtual_address_space_kb/1024) AS Total_VAS_in_MB,
process_physical_memory_low,
process_virtual_memory_low
FROM sys.dm_os_process_memory;

Bildbeschreibung hier eingeben

Wenn ich meine Abfrage mit einem Zeitraum von einem Jahr durchführe, wird keine Warnung angezeigt, wie in der folgenden Abbildung dargestellt:

Bildbeschreibung hier eingeben

Aber wenn ich es nur für 1 Tag laufen lasse, erhalte ich diese Warnung on the sort operator:

Bildbeschreibung hier eingeben

Dies ist die Abfrage:

    DECLARE @FromDate SMALLDATETIME = '19-OCT-2016 11:00'
    DECLARE @ToDate   SMALLDATETIME = '20-OCT-2016 12:00'




    SELECT      DISTINCT
                a.strAccountCode ,
                a.strAddressLine6 ,
                a.strPostalCode ,
                CASE    WHEN a.strCountryCode IN ('91','92') THEN 'GB-Int'
                        ELSE a.strCountryCode
                        END AS [strCountryCode]
    FROM        Bocss2.dbo.tblBAccountParticipant AS ap
    INNER JOIN  Bocss2.dbo.tblBAccountParticipantAddress AS apa ON ap.lngParticipantID = apa.lngParticipantID
                                                                AND apa.sintAddressTypeID = 2
    INNER JOIN  Bocss2.dbo.tblBAccountHolder AS ah ON ap.lngParticipantID = ah.lngParticipantID
    INNER JOIN  Bocss2.dbo.tblBAddress AS a ON apa.lngAddressID = a.lngAddressID
                                            AND a.blnIsCurrent = 1
    INNER JOIN  Bocss2.dbo.tblBOrder AS o ON ap.lngParticipantID = o.lngAccountParticipantID
                                        AND o.sdtmOrdCreated >= @FromDate
                                        AND o.sdtmOrdCreated < @ToDate

OPTION(RECOMPILE)

Der Abfrageplan ist hier

den Abfrageplan mit pastetheplan

Fragen: 1) Im Abfrageplan sehe ich Folgendes:

StatementOptmEarlyAbortReason="GoodEnoughPlanFound" CardinalityEstimationModelVersion="70" 

warum 70? Ich benutze SQL Server 2014

2) Wie werde ich diesen Sortieroperator los (wenn überhaupt möglich)?

3) Ich habe festgestellt, dass die Lebenserwartung der Seiten sehr niedrig ist, abgesehen davon, dass der Server mehr Arbeitsspeicher hat. Kann ich noch etwas anderes überprüfen, um zu sehen, ob ich diese Warnung verhindern kann?

Prost

Update nach der Antwort von Shanky und Paul White

Ich habe meine Statistiken gemäß dem folgenden Skript überprüft und sie scheinen alle korrekt und aktualisiert zu sein.

Dies sind alle in dieser Abfrage verwendeten Indizes und Tabellen.

DBCC SHOW_STATISTICS ('dbo.tblBAddress','IDXF_tblBAddress_lngAddressID__INC')
GO
DBCC SHOW_STATISTICS  ('dbo.tblBOrder','IX_tblBOrder_sdtmOrdCreated_INCL')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountHolder','PK_tblAccountHolder')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountParticipant','PK_tblBAccountParticipants')
GO
DBCC SHOW_STATISTICS ('dbo.tblBAccountParticipantAddress','IDXF_tblBAccountParticipantAddress_lngParticipantID')
GO

das ist was ich zurückbekommen habe:

Bildbeschreibung hier eingeben

Bildbeschreibung hier eingeben

Dies ist ein Teilergebnis, aber ich habe sie alle noch einmal besucht.

Für die Aktualisierung der Statistiken habe ich derzeit Ola Hallengren

Der Index-Optimierungsjob - wird voraussichtlich einmal pro Woche - sonntags ausgeführt

EXECUTE [dbo].[IndexOptimize] 
@Databases = 'USER_DATABASES,-%Archive', 
@Indexes = 'ALL_INDEXES' , 
@FragmentationLow = NULL,
@FragmentationMedium = NULL,
@FragmentationHigh = NULL,
@PageCountLevel=1000,
@StatisticsSample =100
,@UpdateStatistics = 'Index', 
@OnlyModifiedStatistics = 'Y',
@TimeLimit=10800, 
@LogToTable = 'Y'

Obwohl die Statistiken aktualisiert zu sein schienen Nachdem ich das folgende Skript ausgeführt habe, wurde der Sortieroperator nicht mehr gewarnt.

UPDATE STATISTICS [Bocss2].[dbo].[tblBOrder]  WITH FULLSCAN
--1 hour  04 min 14 sec

UPDATE STATISTICS [Bocss2].[dbo].tblBAddress  WITH FULLSCAN
-- 45 min 29 sec

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountHolder WITH FULLSCAN
-- 26 SEC

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountParticipant WITH FULLSCAN
-- 4 min

UPDATE STATISTICS  [Bocss2].[dbo].tblBAccountParticipantAddress WITH FULLSCAN
-- 7 min 3 sec

Wie viel wurde die Abfragezeit reduziert?
Einfluss

Ich könnte niemals eine Lösung implementieren, die es mir ermöglicht, die Statistiken an so großen Tischen auf dem neuesten Stand zu halten. Die Lösung wäre, die Tabellen zu partitionieren und inkrementelle Statistiken zu verwenden, aber ich bin nie dazu gekommen, sie zu implementieren, weil ich diesen Arbeitgeber verlassen habe. Etwas, das ich gerne umgesetzt hätte.
Marcello Miorelli

Antworten:


16

was ist mit Level 2? Ich konnte nichts in Bezug auf Level 2 finden.

Gemäß dieser blog.msdn der Zahl in Tempdb spill bedeutet , wie viele Pässe über Daten erforderlich ist , um die Daten zu sortieren. Spill 1 bedeutet also, dass es 1 Mal passieren muss, um die Daten zu sortieren, und 2 bedeutet, dass es 2 Mal passieren muss.

Zitat aus dem Blog:

Wenn eine Abfrage, die eine Sortieroperation umfasst, eine Sortierwarnungsereignisklasse mit der Überlaufstufe 2 generiert, kann die Leistung der Abfrage beeinträchtigt werden, da zum Sortieren der Daten mehrere Durchläufe über die Daten erforderlich sind. Im folgenden Beispiel sehen wir einen Überlaufwert von 1, was bedeutet, dass ein Durchlauf über die Daten ausreichte, um die Sortierung abzuschließen.

warum 70? Ich benutze SQL Server 2014

Dies liegt daran, dass der Kompatibilitätsgrad der Datenbank in Bild NICHT 120 ist (was den Kompatibilitätsgrad der Datenbank von 2014 angibt), da bei einer Abfrage, die nicht 120 ist, das alte Modell zur Schätzung der Kardinalität (CE) verwendet wird, das als bezeichnet wird CardinalityEstimationModelVersion="70". Sie sind sich sicher bewusst, dass wir ab SQL Server 2014 ein neues CE haben.

Wie werde ich diesen Sortieroperator los (wenn überhaupt möglich)?

Der eindeutige Befehl, den Sie verwenden, verursacht den Sortiervorgang. Die Daten, die sortiert werden, passen nicht in den Speicher, sodass sie in Tempdb verschoben werden. In diesem Fall wird im Ausführungsplan eine Sortierwarnung mit gelbem Ausrufezeichen angezeigt. Sortierwarnungen sind nicht immer ein Problem.

Sie können im Ausführungsplan sehen, dass die geschätzte Anzahl der zu sortierenden Zeilen 1 ist, aber zur Laufzeit 16.353 angetroffen werden. Die für die Sortierung reservierte Speichermenge basiert auf der erwarteten Menge (geschätzten) Größe der Eingabe und kann während der Ausführung (in diesem Fall) nicht vergrößert werden.

Die geringe Speicherzuweisung für die Abfrage (1632 KB) wird auch auf gleichzeitig ausgeführte speicherintensive Operatoren aufgeteilt (sortieren und optimierte Schleifenverknüpfungen). In Ihrem Plan bedeutet dies, dass beim Lesen von Zeilen 33,33% (544 KB) für die Sortierung verfügbar sind (Eingabespeicheranteil). Dies ist nicht genug Speicher, um die 16.353 Zeilen zu sortieren . Ein einziges Verschütten reicht nicht aus, um die Sortierung abzuschließen. Daher ist ein zweites Verschütten erforderlich (weitere Informationen zu den Verschütteniveaus finden Sie am Ende der Referenz).

Eigenschaften sortieren

Sortieren Sie die Eigenschaften so, wie sie im SQL Sentry Plan Explorer angezeigt werden

Das Aktualisieren von Statistiken wird wahrscheinlich beim Problem der Kardinalitätsschätzung helfen. Möglicherweise tritt das Problem mit den aufsteigenden Schlüsseln auf, insbesondere auf dem Tisch tblBOrder. Bei einer einfachen Auswahl aus dieser Tabelle mit den wörtlichen Daten aus Ihrer Frage wird derzeit wahrscheinlich eine Zeile geschätzt.

Ich habe festgestellt, dass die Lebenserwartung von Seiten ziemlich niedrig ist, abgesehen davon, dass dieser Server mehr Arbeitsspeicher hat. Kann ich noch etwas anderes überprüfen, um zu sehen, ob ich diese Warnung verhindern kann?

PLE ist ein Hinweis auf die Größe der E / A-Aktivität. Das passiert also häufig oder nur, wenn Sie eine bestimmte Abfrage ausführen oder dies erst heute geschehen ist. Vermeiden Sie Ruckreaktionen. Zuerst müssen wir sicherstellen, dass Sie wirklich mit Speicherdruck konfrontiert sind, oder dass eine Schurkenabfrage, die zu viel E / A generiert, dies verursacht. Auf jeden Fall ist SQL Server bereits ein 97-G-Speicher zugewiesen.

Weitere Informationen zu Überlaufmengen und dem aufsteigenden Schlüsselproblem finden Sie unter:

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.