Поскольку вы спросили «почему», я собираюсь дать вам полный ответ:)
Выполнение DBCC FREEPROCCACHE
и DBCC DROPCLEANBUFFERS
на периодической основе не является эффективным решением вашей проблемы.Как и при перезапуске, если что-то улучшается, это только по стечению обстоятельств, и вы, скорее всего, увидите ошибочные результаты.Вполне возможно, что, если это «исправление» исправит вашу проблему с производительностью, оно вернется в будущем, казалось бы, случайно и с большей серьезностью, чем вы видите сейчас.
Когда вы запускаете DBCC FREEPROCCACHE
, SQL Serverбудет перекомпилировать каждую хранимую процедуру или кешированный план запроса, который у нее будет при следующем запуске.Если выяснится, что SQL Server выбирает планы, которые лучше подходят для общей работы при следующем запуске, вы, как правило, увидите повышение производительности.Если SQL Server выберет план, который обычно работает хуже, вы увидите снижение производительности.Зачем ему выбирать план, который в целом хуже?Ну, это зависит от первого запроса, который будет выполнен - SQL Server выберет план для оператора на основе избирательности переданных параметров.Взгляните на этот пример:
SET NOCOUNT ON;
IF OBJECT_ID('temporary_demo') IS NOT NULL DROP TABLE temporary_demo;
IF OBJECT_ID('temporary_demoproc') IS NOT NULL DROP PROC temporary_demoproc;
GO
CREATE TABLE temporary_demo (id int primary key identity(1,1), id2 int, txtval nvarchar(100));
insert temporary_demo (id2, txtval) values (1, 'something highly selective');
declare @i int;
set @i = 1;
while @i < 10000 begin
insert temporary_demo (id2, txtval) select 2, 'something else ';
set @i = @i + 1;
end
insert temporary_demo (id2, txtval) select 2, 'needle in a haystack';
create index ix_id2 on temporary_demo(id2);
GO
create proc temporary_demoproc @searchid int, @searchtxtval nvarchar(100) as
select * from temporary_demo where id2 = @searchid and txtval = @searchtxtval;
GO
--Look at the query plans for both of these procedures.
--Note that the plan chosen depends on which one is called first.
exec temporary_demoproc 1, 'something highly selective';
exec temporary_demoproc 2, 'needle in a haystack';
dbcc freeproccache;
exec temporary_demoproc 2, 'needle in a haystack';
exec temporary_demoproc 1, 'something highly selective';
Итак, из примера видно, что если ваша производительность увеличивается из-за вызова DBCC FREEPROCCACHE
, скорее всего, вы даете своему приложению шанс получить другой план запроса для ваших запросов при следующем запуске.Опять же - только случайно или случайно ваше приложение будет работать быстрее (или медленнее).
Что касается DBCC DROPCLEANBUFFERS
, периодическое выполнение этого кода почти всегда замедляет работу вашего приложения.Эта команда заставляет запросы идти в подсистему хранения вместо чтения кэшированных страниц из памяти.Единственный способ, которым я могу думать о том, что это может помочь производительности, - это если конфигурация памяти вашего сервера баз данных неправильна, и он переключается на файл подкачки, потому что ему не хватает физической памяти.
Так в чем же решение?
Решение состоит в том, чтобы не искать общую причину или лейкопластырь.Вам нужно будет выполнить трассировку ваших плохо выполняющихся запросов с использованием профилировщика SQL Server и определить отдельные запросы, которые являются проблематичными.Вам нужно будет сделать некоторые «гайки и болты» анализ этих запросов и действительно понять их.Вам нужно будет выяснить, нужно ли добавлять, изменять или даже удалять индексы в зависимости от запроса, и вам нужно будет идентифицировать проблемные запросы, которые, возможно, придется переписать.