2015-12-01 2 views
1

Ниже представлена ​​моя программа для измерения времени, выполняемого ExecuteScalar для множественной итерации.Почему ExecuteScalar требует времени для первого звонка?

static void Main(string[] args) 
{ 
    string sqlConnectionString = "Data Source=.\\SQLEXPRESS;Initial Catalog=Test;Integrated Security=True"; 
    SqlConnection connection = new SqlConnection(sqlConnectionString); 
    for(int i=0; i <4; i++){ 
     Stopwatch stopWatch = new Stopwatch(); 

     string sqlCommand = "Insert into TestTable (SNO, Name) values (" + i + ",' " + i + "')"; 
     SqlCommand command = new SqlCommand(sqlCommand, connection); 
     connection.Open(); 
     stopWatch.Start(); 
     var result = command.ExecuteScalar(); 
     stopWatch.Stop(); 
     connection.Close(); 
     Console.WriteLine("Time elapsed to insert row " + i + " : " + stopWatch.ElapsedMilliseconds); 
    } 
    Console.ReadKey(); 
} 

Выход:

Time elapsed to insert row 0 : 3 
Time elapsed to insert row 1 : 1 
Time elapsed to insert row 2 : 0 
Time elapsed to insert row 3 : 0 

Мой вопрос, почему он принимает 3 миллисекунды первой итерации и для остальных это меньше, чем это.

Заранее спасибо.

+2

[Объединение пулов SQL Server] (https://msdn.microsoft.com/en-us/library/8xx3tyca (v = vs.110) .aspx) - при первом запуске 'connection.Open', это действительно нужно построить реальное соединение с сервером. В последующих прогонах он, вероятно, снова подключается к тому же соединению. –

+1

Разве что разница в 2 миллисекунды? Может быть, из-за пула соединений? –

+0

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

ответ

1

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

В общем, вы также можете учитывать кэширование плана запроса и фактическое кэширование данных из СУБД, но в этом случае это действительно не относится к операциям INSERT (все же необходимые метаданные для него могут быть холодными в течение первого итерация).

1

Прежде всего, вы должны использовать метод ExecuteNonQuery(). Теперь поговорим о времени; сначала он должен установить соединение, а затем выполнить запрос, но для более поздней итерации это уже не так.

2

Это связано с подключением. После того, как вы установили соединение (независимо от того, закрыли его или нет), пока ваша строка соединения остается неизменной, соединения объединяются, что приводит к более быстрым последовательным выполнению.

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