Диагностика медленных операторов выбора JDB C для SQL сервера, работающего на виртуальной машине Hyper-V - PullRequest
0 голосов
/ 27 февраля 2020

Мы только что создали новую виртуальную машину Hyper-V для размещения приложения Java и сервера Microsoft SQL. Мы столкнулись с очень медленными ответами из базы данных при запуске SQL запросов на выборку из приложения Java JDB C. Те же самые запросы выполняются быстро при запуске из SQL Server Management Studio.

Мы запустили одни и те же Java приложения и SQL Серверные базы данных на голом железе и на виртуальных машинах VMware без каких-либо проблем с производительностью.

Наши вопросы:

  • Видели ли другие разработчики аналогичные проблемы с производительностью в виртуальной машине Hyper-V?
  • Как мы можем диагностировать причины узкого места в производительности для приложения JDB C?

Пример запроса:

select * from view1 where app_id in (
    select app_id from app_table where app_id % 1000 = 0)
order by app_id

Время отклика:

  • SQL Сервер: 45 тыс. строк от 9 до 36 секунд, в зависимости от ОЗУ, процессоров и т. Д. c
  • Java приложение: более 4 часов

виртуальная машина Hyper-V

  • Windows Сервер 2019 хоста
  • Конфигурация Hyper-V 9, поколение 2

Таблица app_table содержит только два столбца.

create table app_table (
  app_id [numeric](18,0) not null,
  col_2 [varchar] (75)
)

Представление app_view: также просто.

create view app_view as select app_id from app_table

Мы пробовали различные комбинации Java приложений катионы, драйверы JDB C и SQL Сервер.

Приложения:

  • Наше пользовательское Java приложение
  • Клиент SQuirreL (4.0.0)

JDB C драйверы:

  • sqljdbc4
  • sqljdbc_8.2.0.jre

SQL Версии сервера:

  • SQL Сервер 2017
  • SQL Сервер 2019

Java версия: 8_241

РЕДАКТИРОВАТЬ: SQL Результаты Profiler

Я не уверен, что лучший способ сообщить SQL результаты профилирования, поэтому я просто подведу итоги, что SQL Profiler сообщает. Клиент SSMS выполняет запрос представления за 23 секунды. Клиенту JDB C потребовалось более 100 секунд, прежде чем запрос был отменен до его завершения.

Для клиента SSMS

SQL: BatchStarting"select * from app_view where ..." 2020-02-26 20: 04: 22 * ​​1074 * <куча повторяющихся вещей>
Аудит входа / выхода из системы
RP C: Завершено "exe c sp_reset_connection"
BatchStarting / Completed "УСТАНОВИТЬ УРОВЕНЬ ИЗОЛЯЦИИ ТРАНЗАКЦИИ ЧИТАТЬ ..."
</ конец группы повторяющихся вещей> **SQL: BatchCompleted "выберите * из app_view где ..." 2020-02-26 20:04:45

для клиента JDB C (SQuirreL)

SQL: BatchStarting"select * from app_view where ..." 2020-02-26 19: 55: 39
<куча повторяющихся вещей>
Audit Login / Выход из системы
RP C: Завершено "exe c sp_reset_connection"
BatchStarting / Завершено "УСТАНОВИТЬ УРОВЕНЬ ИЗОЛЯЦИИ ТРАНЗАКЦИИ ЧИТАТЬ ..." *
</ конец группы повторяющихся вещей>
Запрос отменен в 19: 57: 26

РЕДАКТИРОВАТЬ 2: Больше SQL Результаты профилировщика

Я профилировал более простой запрос "выберите top 5000 a.app_id из app_table а в SSMS и клиенте JDB C. Удивительно, но оба выполняются быстро, менее чем за 1 секунду.

Для клиента SSMS

SQL: BatchStarting"top 5000 a.app_id из app_table a" 2020 -02-27 10: 27: 55.740
SQL: BatchCompleted"top 5000 a.app_id из app_table a" 2020-02-27 10: 27: 55.810

Для клиент JDB C (SQuirreL)

SQL: BatchStarting"top 5000 a.app_id из app_table a" 2020-02-27 10: 25: 45.063
SQL: BatchCompleted"top 5000 a.app_id из app_table a" 2020-02-27 10: 25: 45.843

Ответы [ 2 ]

0 голосов
/ 29 февраля 2020

Хорошо, итак, мы получаем эти результаты.

Редактировать:

Краткий ответ на вопрос: клиент не должен иметь значения столько (то есть: не должно быть такого большого расхождения между SSMS и Net против JDB C и т. д. 1039 *.) Что касается Hyper-V и bare- металл, голый металл выигрывает (если ваши диски виртуализированы) по понятным причинам. Вы можете запустить некоторые тесты ввода-вывода, чтобы доказать это, используя DiskSpd (https://aka.ms/diskspd) в виртуальной машине или в аналогичной среде c d-metal.

Однако - Я не уверен, что все эти проблемы являются проблемой. Основываясь на ваших результатах трассировки, ОБА клиенты показали хорошие результаты по сравнению с базовой таблицей. Оба клиента работали относительно плохо (клиент Java хуже, чем SSMS). Итак, я все равно рекомендую, по крайней мере:

  1. Refre sh представление (как упоминалось ранее)
  2. Попробуйте простой SELECT TOP 5000 * FROM dbo.app_view (из обоих клиенты) - без предложения WHERE - сравните результаты.
  3. Проверьте фрагментацию индекса в базовой таблице в SSMS (щелкните правой кнопкой мыши «папку» индексов под таблицей, нажмите «Перестроить все», посмотрите на цифры в диалоговом окне.) Даже индексы PK может стать фрагментированным, что может привести к снижению производительности c.

  4. Попробуйте другую версию исходного запроса, например:

    SELECT * FROM dbo.app_view где app_id% 1000 = 0

(без SELECT ... WHERE IN ...)

Наконец, сколько столбцов находится в выходных данных фактического представления ? (Если представление достаточно широкое, оно может негативно повлиять на производительность клиента из-за объема сетевого трафика c, а также рендеринга данных на стороне клиента.)

0 голосов
/ 27 февраля 2020

Во-первых, давайте посмотрим, является ли проблема на самом деле SQL Сервером, приложением или другим. Откройте SQL Profiler и запустите трассировку.

При запущенной трассировке выполните следующие запросы:

  • SELECT TOP 5000 a.app_id FROM dbo.app_table a; (запустите эту SSMS)
  • SELECT TOP 5000 a.app_id FROM dbo.app_table a; (запустите это в своем приложении / JDB C клиенте)

(Чтобы быть точным, вы можете повторить приведенные выше операторы SELECT против вашего взгляда.)

Остановите трассировку и запишите время выполнения (продолжительность) из соответствующих приложений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...