Как я удаляю определенный плохой план из кэша запроса SQL Server?

Единственный способ защитить себя от неразборчивого режима к защите :) Но серьезно, если Вы не запускаете Linux на всех своих машинах и компилируете ядро, чтобы удостовериться, что они наклоняются, не предоставляйте доступ машины к BIOS/начальной загрузке и не блокируйте вниз свои рабочие станции Ваш в значительной степени завинченный...

Где хотение, там и умение. можно осуществить сниффинг трафика переключателя btw...

33
задан 5 December 2009 в 11:53
3 ответа

Я выяснил несколько вещей

select * from sys.dm_exec_query_stats

покажет все кэшируемые планы запросов. К сожалению, никакой код на SQL не показывают там.

Однако можно соединить код на SQL с планами как так:

select plan_handle, creation_time, last_execution_time, execution_count, qt.text
FROM 
   sys.dm_exec_query_stats qs
   CROSS APPLY sys.dm_exec_sql_text (qs.[sql_handle]) AS qt

Отсюда это довольно тривиально для добавления a WHERE пункт для нахождения SQL, который я знаю, находится в запросе, и затем я могу выполниться:

DBCC FREEPROCCACHE (plan_handle_id_goes_here)

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

править: дамп всего кэша запроса будет также работать и менее опасен, чем это звучит, по крайней мере по моему опыту:

DBCC FREESYSTEMCACHE ('ALL') WITH MARK_IN_USE_FOR_REMOVAL;
39
ответ дан 28 November 2019 в 19:54
  • 1
    совет использовать подсказку плана стоит тем не менее. –  Remus Rusanu 5 December 2009 в 08:49

Если Вы знаете, как хороший план похож, просто используйте подсказку плана.

Вы не можете удалить определенную запись кэша, но можно убрать весь пул кэша с DBCC FREESYSTEMCACHE(cachename/poolname).

Можно получить название кэша плохого плана запросов, если у Вас есть дескриптор плана (от sys.dm_exec_requests.plan_handle для session_id в проблеме во время выполнения, или от выполнения сообщения sys.dm_exec_query_stats):

select ce.name
from sys.dm_exec_cached_plans cp
join sys.dm_os_memory_cache_entries ce on cp.memory_object_address = ce.memory_object_address
where cp.plan_handle = @bad_plan

Однако все планы SQL имеют имя 'Планы SQL', который делает выбор правильного для DBCC FREESYSTEMCACHE... трудным выбором.

Обновление

Nevermind, забыл о DBCC FREEPROCCACHE(plan_handle), да, который будет работать.

6
ответ дан 28 November 2019 в 19:54
  • 1
    Способность передать plan_handle DBCC FREEPROCCACHE доступна в SQL Server 2008 а не в SQL Server 2005. –  Mario 16 January 2010 в 01:12

Решение FREEPROCCACHE отличное, но более прямой способ сделать это - использовать OPTION (RECOMPILE) на вашей SQL строке (вы упомянули, что это не SP), это говорит движку о его плане Single Use Plan, потому что, вероятно, вы подозреваете, что есть Parameter Sniffing, или ваша статистика резко отличается от запущенного к запуску, и вы подозреваете, что это проблема с плохо кэшированным планом.

DECLARE @SQL NVARCHAR(4000)
SELECT @SQL = 'SELECT * FROM Table WHERE Column LIKE @NAME OPTION (RECOMPILE)'
EXEC sp_executesql @SQL, N'@NAME varchar(15)', 'MyName' 
1
ответ дан 28 November 2019 в 19:54

Теги

Похожие вопросы