Більшість планів запитів відтворені за останні 4 години


9

У мене проблема з роботою моєї бази даних SQL Server. Я знайшов цей інструмент sp_BlitzCache . Після виконання команди я отримав це твердження:

У вас 92,00% планів, створених за останні 24 години, та 92,00% створених за останні 4 години.

Поки я визначив проблему (використовуючи Profiler SQL Server, я перевірив події StmtRecompile), мені вдалося знайти лише кілька повнотекстових пошукових запитів, які часто відновлюються. Однак повнотекстові пошукові запити складають близько 5% усіх запитів.

Чи є у вас якісь пропозиції, що може спричинити рекреацію решти 87% планів?

У мене є SQL Server 2012 (версія 11.0.6567.0).

Редагувати: я додав свої лічильники ефективності

+---------------------------+--------------------------------+--------------+
|        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 |
+---------------------------+--------------------------------+--------------+

Можливо, хтось керував DBCC FREEPROCCACHE? : P
Даніель Бьорк

@ DanielBjörk Я єдина людина, яка має дозвіл робити такі речі, тому я не думаю, що це причина. Однак я це перевірю.
Марцін Тополевський

Використовуєте параметризовані запити чи збережені процедури? чи проблема в тому, що у вашому SQL є літеральні рядки / числа, і тому плани не можна повторно використовувати?
Джеймс Z

@JamesZ Так, я використовую безліч параметризованих запитів. Інструмент, про який я згадував у своєму дописі, BlitzCache, говорить про те, що у мене проблема з нюханням параметрів.
Марцін Тополевський

1
Ви перебудовуєте індекси чи оновлюєте статистику щоночі? Можливо, на сервері є тиск пам'яті?
Ерік Дарлінг

Відповіді:


6

Запит, який використовується для тестування часу створення плану, такий

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) ;

Також SP надає деякі підказки щодо того, з чого почати ваше подальше дослідження

Якщо ці відсотки високі, це може бути ознакою тиску пам'яті або нестабільності кешу плану

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

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

  • перевірте, чи не стикається ваш тиск пам'яті

Спочатку дивіться, якщо налаштування вашої пам’яті налаштовано оптимально. Якщо це так, ви можете використовувати лічильники нижче, щоб побачити, чи не стикаєтесь ви з тиском пам'яті

Пам'ять: Доступний
буфер MB SQL: Безкоштовні сторінки
Буфер SQL: Сторінка сторінки Буфер
SQL: Ледачий запис

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

ви могли запускати запити, що викликають перекомпіляцію. Деякі з них включають

  • Зміни, внесені до таблиці або перегляду, на які посилається запит (ALTER TABLE та ALTER VIEW).

  • Зміни, внесені до єдиної процедури, які б вивели всі кеші для цієї процедури з кешу (ALTER PROCEDURE).

  • Зміни будь-яких індексів, які використовуються планом виконання

  • Оновлення статистики, використовуваної планом виконання, генерується або явно з заяви, наприклад ОНОВЛЕННЯ СТАТИСТИКИ, або генерується автоматично.

  • Випадання індексу, який використовується планом виконання.

Ви також можете побачити цю білу книгу, щоб отримати докладнішу інформацію про кешування плану

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


Я додав свої лічильники ефективності, чи можете ви допомогти мені інтерпретувати ці значення?
Марцін Тополевський

Ви можете шукати докладні лічильники пам’яті тут: blogs.msdn.microsoft.com/teekamg/2007/11/06/…
TheGameiswar

@TheGameiswar ви кажете, що "ви могли запускати запити, що викликають перекомпіляцію ... наприклад зміни в індексах, оновлення статистики". Якщо я роблю індекс reorg / rebuild на основі фрагментації + оновлення статистики щовечора, чи це означає, що мої плани будуть (або майже всі) відтворюватися щодня? це проблема?
Даніель Пакет-Харві

2

Щоб додати те, що сказав @TheGameiswar, ви також можете запустити цей запит, щоб переглянути деталі планів, які не отримані з кешу.

;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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.