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

9

У меня проблема с производительностью базы данных SQL Server. Я нашел этот инструмент sp_BlitzCache . После выполнения команды я получил следующее утверждение:

У вас есть планы на 92,00%, созданные за последние 24 часа, и 92,00%, созданные за последние 4 часа.

Хотя я обнаружил проблему (используя SQL Server Profiler, я проверил вхождения событий 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 есть строковые / числовые литералы, и поэтому планы не могут быть повторно использованы?
Джеймс З
@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 предоставляет некоторые подсказки о том, где начать ваше дальнейшее исследование

Если эти проценты высоки, это может быть признаком нехватки памяти или плановой нестабильности кэша

Кроме вышеупомянутых подсказок, проверьте, был ли ваш сервер перезапущен.

если ваш сервер не перезагружается, то нижеприведенный подход

  • проверьте, не противостоит ли вам давление

Сначала посмотрите, если ваши настройки памяти настроены оптимально. Если это так, вы можете использовать ниже счетчики, чтобы увидеть, если вы сталкиваетесь с давлением памяти

Память: доступно МБ
Буфер SQL: Свободные страницы
Буфер SQL: Жизнь страницы Буфер
SQL: Ленивые записи

если вы сталкиваетесь с нехваткой памяти, вы можете увидеть и настроить запросы, которые используют больше памяти, или попробуйте добавить больше памяти

Вы могли запустить запросы, которые вызывают перекомпиляцию. Некоторые из них включают в себя

  • Изменения, внесенные в таблицу или представление, на которые ссылается запрос (ALTER TABLE и ALTER VIEW).

  • Изменения, внесенные в одну процедуру, которая удаляла бы все планы для этой процедуры из кэша (ALTER PROCEDURE).

  • Изменения любых индексов, используемых планом выполнения

  • Обновления статистики, используемые планом выполнения, генерируемые либо явно из инструкции, такой как UPDATE STATISTICS, либо генерируемые автоматически.

  • Удаление индекса, используемого планом выполнения.

вы также можете увидеть этот документ для более подробной информации о планировании кэширования

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

TheGameiswar
источник
Я добавил свои счетчики производительности, не могли бы вы помочь мне интерпретировать эти значения?
Марчин Тополевски
Вы можете посмотреть подробные счетчики, связанные с памятью, здесь: 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;
Декан савович
источник