Die meisten Abfragepläne wurden in den letzten 4 Stunden neu erstellt

9

Ich habe ein Problem mit der Leistung meiner SQL Server-Datenbank. Ich habe dieses Tool sp_BlitzCache gefunden . Nachdem der Befehl ausgeführt wurde, erhielt ich folgende Anweisung:

Sie haben 92,00% Pläne in den letzten 24 Stunden und 92,00% in den letzten 4 Stunden erstellt.

Während ich das Problem identifizierte (mit SQL Server Profiler habe ich das Auftreten von StmtRecompile-Ereignissen überprüft), konnte ich nur einige Volltextsuchabfragen finden, die häufig neu erstellt werden. Volltextsuchabfragen machen jedoch nur etwa 5% aller Abfragen aus.

Haben Sie Vorschläge, was zur Wiederherstellung der verbleibenden 87% -Pläne führen könnte?

Ich habe SQL Server 2012 (Version 11.0.6567.0).

Bearbeiten: Ich habe meine Leistungsindikatoren hinzugefügt

+---------------------------+--------------------------------+--------------+
|        object_name        |          counter_name          |  cntr_value  |
+---------------------------+--------------------------------+--------------+
| SQLServer:Buffer Manager  | Background writer pages/sec    |            0 |
| SQLServer:Buffer Manager  | Buffer cache hit ratio         |        28436 |
| SQLServer:Buffer Manager  | Buffer cache hit ratio base    |        28436 |
| SQLServer:Buffer Manager  | Checkpoint pages/sec           |      8259452 |
| SQLServer:Buffer Manager  | Database pages                 |      4434337 |
| SQLServer:Buffer Manager  | Free list stalls/sec           |            9 |
| SQLServer:Buffer Manager  | Integral Controller Slope      |            0 |
| SQLServer:Buffer Manager  | Lazy writes/sec                |         5608 |
| SQLServer:Buffer Manager  | Page life expectancy           |       438901 |
| SQLServer:Buffer Manager  | Page lookups/sec               | 122694703703 |
| SQLServer:Buffer Manager  | Page reads/sec                 |     60994608 |
| SQLServer:Buffer Manager  | Page writes/sec                |    126076564 |
| SQLServer:Buffer Manager  | Readahead pages/sec            |     45305420 |
| SQLServer:Buffer Manager  | Target pages                   |    130990080 |
| SQLServer:Buffer Node     | Database pages                 |      4434337 |
| SQLServer:Buffer Node     | Page life expectancy           |       438901 |
| SQLServer:Buffer Node     | Local node page lookups/sec    |            0 |
| SQLServer:Buffer Node     | Remote node page lookups/sec   |            0 |
| SQLServer:Memory Manager  | External benefit of memory     |            0 |
| SQLServer:Memory Manager  | Connection Memory (KB)         |         3304 |
| SQLServer:Memory Manager  | Database Cache Memory (KB)     |     35474784 |
| SQLServer:Memory Manager  | Free Memory (KB)               |     13229808 |
| SQLServer:Memory Manager  | Granted Workspace Memory (KB)  |            0 |
| SQLServer:Memory Manager  | Lock Memory (KB)               |       455928 |
| SQLServer:Memory Manager  | Lock Blocks Allocated          |      1798154 |
| SQLServer:Memory Manager  | Lock Owner Blocks Allocated    |      3568588 |
| SQLServer:Memory Manager  | Lock Blocks                    |        10562 |
| SQLServer:Memory Manager  | Lock Owner Blocks              |        10617 |
| SQLServer:Memory Manager  | Maximum Workspace Memory (KB)  |     43368000 |
| SQLServer:Memory Manager  | Memory Grants Outstanding      |            0 |
| SQLServer:Memory Manager  | Memory Grants Pending          |            0 |
| SQLServer:Memory Manager  | Optimizer Memory (KB)          |         1400 |
| SQLServer:Memory Manager  | Reserved Server Memory (KB)    |            0 |
| SQLServer:Memory Manager  | SQL Cache Memory (KB)          |       229112 |
| SQLServer:Memory Manager  | Stolen Server Memory (KB)      |      8063232 |
| SQLServer:Memory Manager  | Log Pool Memory (KB)           |         4192 |
| SQLServer:Memory Manager  | Target Server Memory (KB)      |     56934400 |
| SQLServer:Memory Manager  | Total Server Memory (KB)       |     56767824 |
| SQLServer:Memory Node     | Database Node Memory (KB)      |     35474784 |
| SQLServer:Memory Node     | Free Node Memory (KB)          |     13229808 |
| SQLServer:Memory Node     | Foreign Node Memory (KB)       |            0 |
| SQLServer:Memory Node     | Stolen Node Memory (KB)        |      8063208 |
| SQLServer:Memory Node     | Target Node Memory (KB)        |     56934376 |
| SQLServer:Memory Node     | Total Node Memory (KB)         |     56767800 |
+---------------------------+--------------------------------+--------------+
Marcin Topolewski
quelle
Vielleicht hat jemand DBCC FREEPROCCACHE ausgeführt? : P
Daniel Björk
@ DanielBjörk Ich bin die einzige Person, die die Erlaubnis hat, solche Dinge zu tun, also denke ich nicht, dass dies der Grund ist. Ich werde es jedoch überprüfen.
Marcin Topolewski
Verwenden Sie parametrisierte Abfragen oder gespeicherte Prozeduren? oder liegt das Problem darin, dass Sie Zeichenfolgen- / Zahlenliterale in Ihrem SQL haben und Pläne daher nicht wiederverwendet werden können?
James Z
@JamesZ Ja, ich verwende viele parametrisierte Abfragen. Das Tool, das ich in meinem Beitrag erwähnt habe, BlitzCache, sagt, dass ich ein Problem mit dem Parameter-Sniffing habe.
Marcin Topolewski
1
Erstellen Sie Indizes neu oder aktualisieren Sie Statistiken jede Nacht? Vielleicht gibt es Speicherdruck auf dem Server?
Erik Darling

Antworten:

6

Die Abfrage zum Testen der Planerstellungszeit lautet:

WITH x AS (
SELECT SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 24 THEN 1 ELSE 0 END) AS [plans_24],
       SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 4 THEN 1 ELSE 0 END) AS [plans_4],
       SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 1 THEN 1 ELSE 0 END) AS [plans_1],
       COUNT(deqs.creation_time) AS [total_plans]
FROM sys.dm_exec_query_stats AS deqs
)
SELECT CONVERT(DECIMAL(3,2), NULLIF(x.plans_24, 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_24],
       CONVERT(DECIMAL(3,2), NULLIF(x.plans_4 , 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_4],
       CONVERT(DECIMAL(3,2), NULLIF(x.plans_1 , 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_1],
       @@SPID AS SPID
INTO #plan_creation
FROM x
OPTION (RECOMPILE) ;

Auch der SP liefert einige Hinweise, wo Sie mit Ihrer weiteren Forschung beginnen können

Wenn diese Prozentsätze hoch sind, kann dies ein Zeichen für Speicherdruck oder Plan-Cache-Instabilität sein

Überprüfen Sie, ob Ihr Server neu gestartet wurde, außer den oben genannten Hinweisen.

Wenn Ihr Server nicht neu gestartet wird, ist unten der Ansatz, den ich verfolgen würde

  • Überprüfen Sie, ob Ihr Speicherdruck vor Ihnen liegt

Überprüfen Sie zunächst, ob Ihre Speichereinstellungen optimal konfiguriert sind. Wenn dies der Fall ist, können Sie anhand der folgenden Zähler feststellen, ob Sie unter Speicherdruck stehen

Speicher: Verfügbar MB
SQL-Puffer: Freie Seiten
SQL-Puffer: Seitenleben
SQL-Puffer: Lazy Writes

Wenn Sie unter Speicherdruck stehen, können Sie die Abfragen anzeigen und optimieren, die mehr Speicher belegen, oder versuchen, mehr Speicher hinzuzufügen

Möglicherweise haben Sie Abfragen ausgeführt, die eine Neukompilierung verursachen. Einige davon enthalten

  • Änderungen an einer Tabelle oder Ansicht, auf die von der Abfrage verwiesen wird (ALTER TABLE und ALTER VIEW).

  • Änderungen an einer einzelnen Prozedur, durch die alle Pläne für diese Prozedur aus dem Cache gelöscht werden (ALTER PROCEDURE).

  • Änderungen an den vom Ausführungsplan verwendeten Indizes

  • Aktualisierungen der vom Ausführungsplan verwendeten Statistiken, die entweder explizit aus einer Anweisung wie UPDATE STATISTICS generiert oder automatisch generiert werden.

  • Löschen eines vom Ausführungsplan verwendeten Index.

In diesem Whitepaper finden Sie weitere Informationen zum Plan-Caching

https://technet.microsoft.com/en-us/library/ee343986(v=sql.100).aspx

TheGameiswar
quelle
Ich habe meine Leistungsindikatoren hinzugefügt. Können Sie mir helfen, diese Werte zu interpretieren?
Marcin Topolewski
Sie können hier nach detaillierten speicherbezogenen Zählern Ausschau
halten
@TheGameiswar Sie sagen "Sie haben möglicherweise Abfragen ausgeführt, die eine Neukompilierung verursachen ... wie Änderungen am Index, Aktualisierung der Statistiken". Wenn ich jede Nacht eine Indexreorganisation / -wiederherstellung basierend auf Fragmentierungs- und Aktualisierungsstatistiken durchführe, bedeutet dies, dass meine Pläne jeden Tag (oder fast alle) neu erstellt werden? ist das ein Problem?
Danielle Paquette-Harvey
2

Um hinzuzufügen, was @TheGameiswar gesagt hat, können Sie diese Abfrage auch ausführen, um die Details von Plänen anzuzeigen, die nicht aus dem Cache abgerufen werden.

;with
    xmlnamespaces (N'http://schemas.microsoft.com/sqlserver/2004/07/showplan' as DYN)
select
    db_name(st.dbid) as DBName
    , object_schema_name(st.objectid, st.dbid) as SchemaName
    , object_name(st.objectid, st.dbid) as ObjectName
    , ecp.objtype
    , st.text
    , qp.query_plan.value('(/DYN:ShowPlanXML/DYN:BatchSequence/DYN:Batch/DYN:Statements/DYN:StmtSimple/@RetrievedFromCache)[1]', 'varchar(100)') as RetrievedFromCache
    , qp.query_plan
into #temp
from sys.dm_exec_cached_plans ecp
    outer apply sys.dm_exec_query_plan(ecp.plan_handle) qp
    outer apply sys.dm_exec_sql_text(ecp.plan_handle) st

select
    *
from #temp t
where t.RetrievedFromCache is null
    and t.DBName is not null
order by t.DBName, t.SchemaName, t.ObjectName;
Dean Savović
quelle