2016-01-20 2 views
5

В настоящее время я вызываю несколько хранимых процедур в некотором .NET-коде, SqlConnection. Я хотел бы отключить кэширование, выполняемое SQL Server, чтобы периодически измерять производительность (я собираюсь сравнить его с другим сервером, который, вероятно, также не будет иметь кэшированных данных). Можно ли это сделать без изменения sprocs?Отключение кэширования SQL Server через код .NET

Это код, который я в настоящее время с помощью:

using (SqlConnection connection = new SqlConnection(/* connection string goes here */)) { 

    SqlCommand command = new SqlCommand(procName, connection); 
    command.Parameters.AddRange(parameters); 
    command.CommandType = System.Data.CommandType.StoredProcedure; 
    connection.Open(); 

    SqlDataReader r = command.ExecuteReader(); 
    // todo: read data here 
    r.Close(); 
    connection.Close(); 
} 
+2

Это сложно. Разве вы не должны измерять производительность кэширования в любом случае, потому что он более репрезентативен? – usr

+0

Как насчет отправки 'dbcc dropcleanbuffers' до вашего запроса? –

+2

Это плохая идея, и вы, скорее всего, не хотите этого делать; вдвойне в производстве. Но если вам нужно, 'dbcc dropcleanbuffers' и' dbcc freeproccache' https://msdn.microsoft.com/en-AU/library/ms187762.aspx и https://msdn.microsoft.com/en-us/library/ ms174283.aspx –

ответ

0

Первая вещь, на «кэширование» здесь я предполагаю, что вы имеете в виду план выполнения кэша. Как только SQL Server определяет лучший порядок выполнения ваших заявлений, он сохраняет его на некоторое время. Эта проблема широко известна как «Snaping параметра». Это то, что вы очищаете при запуске dbcc freeproccache. К сожалению, это привилегированная команда, и она влияет на все соединения.

Корень проблемы заключается в том, что ваш SQL, вероятно, работает по-разному с другим набором параметров. SQL Server будет хранить только план выполнения первого выполнения, который он видит, и связанные с ним параметры. Поэтому, если аргументы при первом выполнении подходят для обычного случая, ваше приложение будет работать нормально. Но время от времени неправильные аргументы будут использоваться при первом выполнении, и все ваше приложение может работать плохо.

Существует несколько способов оптимизации вашего оператора SQL, чтобы уменьшить влияние этого, но его нельзя полностью избежать.

  1. Генерировать SQL динамически - вы принимаете удар производительности при формировании плана запроса при каждом выполнении, но это может быть полезно, если использование неправильного плана выполнения заставляет ваш запрос никогда не возвращаться. Я предлагаю этот путь, хотя он более громоздкий. Я нашел SET STATISTICS TIME ON и SQL Profiler полезен в сокращении времени создания плана. Наибольшее улучшение было достигнуто за счет использования трехзначного наименования (owner.schema.table) для таблиц.
  2. Укажите «хороший набор» исходных параметров для вашего запроса с подсказками запросов.
SELECT Col1, Col2 
FROM dbo.MySchema.MyTab 
WHERE [email protected] 
OPTION (OPTIMIZE FOR (@Parameter='value')); 

Эта ссылка описывает parameter sniffing problem достаточно хорошо. Это была большая проблема в SQL 2005. Более поздние версии SQL лучше справились с этим.

Смежные вопросы