Соединение JDBC с очень занятым SQL 2000: selectMethod = курсор vs selectMethod = direct?

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

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

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

UPDATE. Строка подключения - это строка строки подключения JDBC, selectMethod=cursor (которая позволяет курсоры на стороне сервера, о которых мы говорили выше) и альтернативу selectMethod=direct. Они использовали selectMethod=cursor в качестве стандартной строки соединения из всех приложений.

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

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

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

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

Также перекрестная ссылка на SF.

EDIT: Получены фактические технические данные, которые требуют значительного редактирования заголовков, вопросов и тегов.

EDIT: добавлена ​​награда. Также добавлена ​​щедрость на вопрос SF (этот вопрос ориентирован на поведение приложения, вопрос SF сосредоточен на производительности SQL.) Спасибо!

Ответ 1

Коротко,

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

Таким образом,

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

Ответ 2

Использование selectMethod=cursor предотвращает использование SQL Server Parallel Query Processing, которое может иметь большое влияние на производительность, например, когда:

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

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

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

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