Назад | Перейти на главную страницу

Влияние JDBC на производительность SQL 2000 selectMethod = cursor

(Размещено первым на SO, но ответов там нет. Кросс-постинг для охвата более широкой аудитории, поскольку это междисциплинарный.)

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

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

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

ОБНОВИТЬ: У них есть несколько приложений Java, использующих соединение JDBC с сервером SQL с selectMethod=cursor указано (в отличие от selectMethod=direct).

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

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

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

Обновить: Обнаружено имя параметра драйвера, требующее значительных изменений в заголовке, теле и тегах.

Обновить: Добавлен баунти. Также добавлено вознаграждение за вопрос SO (который больше ориентирован на поведение приложения). Спасибо!

Вкратце,

  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, или связаны каким-либо образом, или когда память не является проблемой.

Ура, В.