Соединение JDBC с очень загруженным SQL 2000: selectMethod= курсор против selectMethod = прямой?

В процессе попытки помочь группе разработчиков приложений с проблемами производительности на сервере SQL 2000 (из набора приложений Java на отдельных серверах приложений) я запустил трассировку SQL и обнаружил, что все вызовы базы данных полны API Операторы серверных курсоров (sp_cursorprepexec, sp_cursorfetch, sp_cursorclose).

Похоже, они задают некоторые свойства строки подключения, которые заставляют использовать серверные курсоры, извлекая только 128 строк данных за раз: (с http://msdn.microsoft.com/en-us/library/Aa172588)

Если для атрибутов или свойств курсора API задано значение, отличное от их значений по умолчанию, поставщик OLE DB для SQL Server и драйвер ODBC для SQL Server используют серверные курсоры API вместо наборов результатов по умолчанию. Каждый вызов функции API, которая извлекает строки, генерирует запрос к серверу для получения строк из курсора сервера API.

ОБНОВЛЕНИЕ: рассматриваемая строка соединения является параметром строки соединения JDBC, selectMethod=cursor (который включает серверные курсоры, которые мы обсуждали выше) против альтернативы selectMethod=direct, Они использовали selectMethod=cursor в качестве стандартной строки подключения из всех приложений.

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

Они, по-видимому, тестировали изменение (только одно из примерно 60 различных подключений приложений) к selectMethod=direct но испытал некоторые проблемы (о которых я не имею подробностей) и обеспокоен взломом приложения.

Итак, мои вопросы:

  • Можно с помощью selectMethod=cursor более низкая производительность приложений, как я пытался спорить? (путем увеличения количества циклов, необходимых на сервере SQL, который уже имеет очень высокие запросы / сек)
  • Является selectMethod= прозрачный для приложения параметр соединения JDBC? Может ли это сломать их приложение, если мы изменим его?
  • В целом, когда вы должны использовать cursor против direct?

Также кросс-пост в SF.

РЕДАКТИРОВАТЬ: Получены фактические технические данные, которые требуют значительного редактирования заголовка, вопроса и тегов.

РЕДАКТИРОВАТЬ: Добавлена ​​щедрость. Также добавлено вознаграждение в вопрос SF (этот вопрос посвящен поведению приложения, вопрос SF посвящен производительности SQL). Спасибо!!

2 ответа

Решение

Коротко говоря,

  1. selectMethod=cursor
    • теоретически требует больше серверных ресурсов, чем selectMethod=direct
    • загружает в память клиента только самое большое количество пакетных записей одновременно, что приводит к более предсказуемому использованию клиентской памяти
  2. selectMethod=direct
    • теоретически требует меньше серверных ресурсов, чем selectMethod=cursor
    • прочитает весь набор результатов в память клиента (если драйвер не поддерживает асинхронный поиск набора результатов), прежде чем клиентское приложение сможет выполнить итерации по нему; это может снизить производительность двумя способами:
      1. снижение производительности при больших наборах результатов, если клиентское приложение написано таким образом, чтобы остановить обработку после прохождения только части набора результатов (с direct он уже окупил стоимость извлечения данных, которые он по сути выбрасывает; с cursor отходы ограничены максимальным размером пакета - 1 строкой - условие досрочного завершения, вероятно, следует в любом случае перекодировать в SQL, например как SELECT TOP или оконные функции)
      2. снижение производительности при больших наборах результатов из-за потенциальных проблем с сборкой мусора и / или нехваткой памяти, связанных с увеличением объема используемой памяти

В итоге,

  • Можно с помощью selectMethod=cursor ниже производительность приложения? - любой метод может снизить производительность по разным причинам. Прошлый размер результирующего набора, cursor все еще может быть предпочтительнее. Смотрите ниже о том, когда использовать один или другой
  • Является selectMethod= прозрачный для приложения параметр соединения JDBC? - это прозрачно, но оно все равно может сломать их приложение, если использование памяти вырастет достаточно значительно, чтобы перегружать их клиентскую систему (и, соответственно, ваш сервер) или вызвать крах клиента
  • В целом, когда вы должны использовать cursor против direct ? - я лично пользуюсь cursor при работе с потенциально большими или иным образом неограниченными результирующими наборами. Затем накладные расходы туда-обратно амортизируются при достаточно большом размере пакета, и мой объем памяти клиента предсказуем. я использую direct когда размер ожидаемого набора результатов, как известно, уступает любому размеру пакета, который я использую cursor или связаны каким-то образом, или когда память не является проблемой.

С помощью selectMethod=cursor запрещает SQL Server использовать параллельную обработку запросов, что может сильно повлиять на производительность, например, когда:

  • у вас много процессорных ядер (а у кого нет?)
  • вы оптимизировали свою базу данных путем разделения таблиц
  • вы выполняете много агрегатных запросов (sum(), count(), так далее.)

Наконец, Microsoft заявляет следующее:

(selectMethod=direct) обеспечивает максимальную производительность, когда приложение обрабатывает все строки.

Вы должны обязательно попробовать и посмотреть, если установка selectMethod=direct имеет значение для вас.

Другие вопросы по тегам