У меня есть экземпляр разработки SQL Server 2022, работающий с данными тестового клиента. Сосредоточив внимание на одном изолированном запросе, запрос представляет собой простой выбор с указанными столбцами и предложениемwhere является первичным ключом кластерного индекса таблиц:
Код: Выделить всё
SELECT col1, col2, col3, col4, col5
FROM table
WHERE key = @key
Выполнение этого запроса постоянно занимает полсекунды. в коде из приложения .NET Framework 4.8 с использованием Microsoft.Data.SqlClient (я пробовал переключиться на System.Data.SqlClient, но не заметил никаких изменений в производительности).
Напротив, в этом приложении есть запросы длиной во многие тысячи строк, которые выполняются за десятые или тысячные доли секунды. Таким образом, это не все запросы, а лишь несколько избранных, и все затронутые запросы представляют собой одну таблицу, очень простые выборки из очень маленьких таблиц.
Более того, это затрагивает только пользователей Windows 11 Pro. , пользователи Windows 10 Pro этого не испытывают.
Моей первой мыслью было, что это должен быть план объяснения, поэтому я очистил кеш и запустил клиенты на двух разных машинах: 11 и 10 — они оба использовали один и тот же план (EDIT*. Это можно воспроизвести в SSMS, см. обновление в конце).
Выполнил трассировку и запрос со стороны сервера, говорит, что выполняется за 0-2 тысячных, но клиент все равно занимает полсекунды или больше.
Я установил еще один экземпляр SQL Server 2022 на компьютере с Windows 11 Pro и восстановил сделал резервную копию проблемной базы данных и не смог воспроизвести проблему. Установил последнее накопительное обновление на обе машины, перезапустил обе, в поведении никаких изменений.
Проблемная база данных размещена на сервере Windows 2019, который за последние несколько месяцев получил ряд обновлений. . К сожалению, области кода, в которых возникают эти проблемы, используются реже, поэтому я не могу достаточно хорошо изолировать их на временной шкале, чтобы предположить, могло ли обновление повлиять на них или нет.
Я выделил запрос в отдельное тестовое приложение, построил строку подключения так же, проблема повторяется. Судя по трассировке сервера, начало и конец выполнения запроса совпадают с точностью до тысячной доли секунды. На стороне приложения я ставлю секундомер перед выполнением запроса, останавливаюсь сразу после него и затем записываю его. Постоянно вижу полсекунды.
Все это сказано, если я изменю запрос на
Код: Выделить всё
SELECT *
FROM table
WHERE key = @key
И здесь я должен повторить: тот же план выполнения используется машиной, которая выполняет это за тысячные доли секунды. Трассировка сервера говорит, что это мгновенно. Восстановленная копия базы данных на другом сервере не демонстрирует такого поведения, и подавляющее большинство других запросов, гораздо более сложных и в больших таблицах, работают нормально - и это не зависит от конкретного исполняемого файла, поскольку это воспроизводится в другом тесте. Программы. Версии базы данных совпадают, проблем с подключением нет, поведение одинаковое.
РЕДАКТИРОВАНИЕ*
Обновление некоторой информации; Тестирование проводилось с одним и тем же пользователем и несколькими пользователями. Есть 3 компьютера с Windows 11 Pro для тестирования и 2 компьютера с Windows 10 Pro для тестирования.
В таблице, о которой идет речь, ровно 35 строк с 20 столбцами, и все они очень маленькие — ничего подобного здесь задействована сумасшедшая капля или что-то еще.
План, используемый из SSMS на Win 11 Pro:
https://www.brentozar.com/ Pastetheplan/?id=SJX-IEILC
План, используемый из SSMS на Win 10 Pro:
https://www.brentozar.com/ Pastetheplan/?id=ryMo9EULC
Скриншот журнала трассировки — на стороне клиента это заняло более полсекунды (Windows 11 Pro):
Trace Журнал
Используемый тестовый код:
Код: Выделить всё
private void button1_Click(object sender, EventArgs e)
{
int RelayCategoryTaskID = Convert.ToInt32(txtTestID.Text);
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = txtServer.Text;
builder.InitialCatalog = txtDatabase.Text;
builder.Encrypt = false;
builder.TrustServerCertificate = false;
builder.ApplicationName = "Test";
builder.ConnectTimeout = 10;
builder.IntegratedSecurity = true;
using (SqlConnection conn = new SqlConnection(builder.ConnectionString))
using (SqlCommand cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = @"
SELECT
[rct].[RelayCategoryTaskID]
, [rct].[RelayCategoryTaskGUID]
, [rct].[RelayCategoryAssociationID]
, [rct].[Name], [rct].[PercentComplete]
, [rct].[StartDate], [rct].[Deadline]
, [rct].[DurationDays]
, [rct].[Constraint]
, [rct].[ConstraintDate]
, [rct].[IsMilestone]
, [rct].[Notes]
, [rct].[ParentRelayCategoryTaskID]
--, rct.AllProperties
FROM
relay_category_task rct WITH (NOLOCK)
WHERE
[rct].[RelayCategoryTaskID] = @RelayCategoryTaskID;";
cmd.Parameters.Add("@RelayCategoryTaskID", System.Data.SqlDbType.Int).Value = RelayCategoryTaskID;
Stopwatch sw = Stopwatch.StartNew();
using (SqlDataReader reader = cmd.ExecuteReader())
{
sw.Stop();
string msg = $"Processed RelayTask {RelayCategoryTaskID} in {sw.Elapsed}";
Debug.Print(msg);
MessageBox.Show(msg);
}
}
}
Код: Выделить всё
Processed RelayTask 17 in 00:00:00.5448354
Выполнение ExecuteNonQuery приводит примерно к такому же результату продолжительность на стороне клиента. Как и тесты SqlDataReader, трассировка выглядит практически так же. Аналогично, сравнение трассировки при ее запуске в Windows 10 (где она работает быстро) выглядит более или менее одинаково.
Я создал другую базу данных на том же сервере, восстановил на ней эту базу данных, и увидеть то же самое поведение. (Здесь я отмечу, как указано выше, но это долго, восстанавливая эту базу данных на другом сервере, я не могу воспроизвести поведение, и поведение стало новым где-то за последние 3-4 месяца, поскольку этот раздел кода был протестирован в феврале. .)
Следует отметить, что на этой машине также установлен экземпляр SQL Server Express. Я остановил экземпляр, те же проблемы с производительностью. Поэтому я полностью удалил экземпляр и установил экспресс - перезапустил, проблема не устранена.
Я установил SQL Server Express с той же конфигурацией на другой тестовый сервер базы данных, восстановил на нем резервную копию, перезапустил. , все еще не могу воспроизвести проблему.
EDIT*
Обновление: нажатие F4 в SSMS показывает, что это также занимает полсекунды для SSMS:
Результаты SSMS
EDIT*
Захват сети Wireshark для выполнения запроса (содержит много шума, заранее извиняюсь), 87 хост-сервер SQL, а 97 — клиентский компьютер с Windows 11 Pro:
Wireshark Network Capture — фильтруется по соответствующему IP-адресу
*EDIT 6/24Пытался откатить обновления на SQL-сервере, без изменений.
Пытался откатить обновления на затронутых машинах, без изменений.
Я все еще Я бы не стал сбрасывать со счетов то, что это вызвано обновлением, я просто не могу решить эту проблему, выполнив резервное копирование - есть ограничения на то, что я могу отменить, и мои архивы резервных копий для ОС не возвращаются достаточно далеко, чтобы быть полезными.< /p>
Я нашел старую, редко используемую машину с Win11 Pro, и на ней нет этой проблемы. Я обновил его, и проблема по-прежнему не возникает.
Я установил версию SQL Server dev на другой компьютер, сейчас это третья копия этой БД, и восстановил на ней базу данных. Проблема воспроизводится и там.
Я установил Wireshark на компьютер разработчика SQL-сервера и трижды выполнил запрос к нему с затронутого компьютера и три раза с незатронутого компьютера. все три теста выполняются из одного и того же тестового приложения.
Результаты, приведенные ниже, показывают, что серверу требуется более 500 мс, чтобы ответить на затронутые машины, но не на незатронутые машины, поэтому задержка полностью серверная часть. Или, по крайней мере, это моя интерпретация этого.
Захват Wireshark с SQL-сервера:
https://drive.google.com/file/d/1jBGEkO ... rFxbiHeZaz /view?usp=drive_link
Аналогичные тесты проводились на клиентских машинах, ссылки на них приведены в комментариях ниже. Эти тесты также указывают на задержку где-то кроме клиента.
Это делает бессмысленным тот факт, что я перезагружал и перенастраивал маршрутизатор, но я сделал и это. Никаких изменений.
Глядя на sys.dm_exec_sessions, затронутые и незатронутые, все настройки совпадают при сравнении сеансов.
*Последний тест ночи - Захват Wireshark на SQL-сервере, трассировка SQL Profiler на SQL-сервере. Выполнили те же три теста на тех же двух машинах, что и раньше.
Для затронутой машины существует задержка примерно 500 мс между моментом, когда Wireshark захватывает полученный пакет, и моментом, когда SQL-сервер сообщает об этом. начал обработку в Trace. Задержка между моментом, когда Trace сообщает о завершении выполнения, и отправкой исходящего пакета клиенту составляет тысячную долю секунды или меньше во всех трех тестах.
EDIT*
Шаги для воспроизведения :
- Включите экземпляр SQL-сервера, SQL Express 2022, SQL Dev 2022 или SQL Enterprise 2022.
- Включите TCP. , установите порт 1433, настройте брандмауэр для трафика SQL.
- Создайте базу данных с настройками по умолчанию.
- Запустите сценарий создания таблицы с данными отсюда: https://pastebin.com/K997QPdE
- Откройте SSMS, нажмите F4, чтобы просмотреть свойства соединения, включая затраченное время, и запустите запрос отсюда: https://pastebin.com/71g3vrpL
Я воспроизвел это на 4 серверах, это не влияет на всех клиентов, но если клиент затронут, он будет демонстрировать такое же поведение, по крайней мере, как кажется, на любом сервере.>
Подробнее здесь: https://stackoverflow.com/questions/786 ... ndows-10-p