SQL-запросы к MSSQL содержат паузы даже при включенном MARS - PullRequest
1 голос
/ 01 сентября 2011

Мы тестируем драйверы JDBC от jTDS и Microsoft, и мы страдаем от нежелательных пауз в выполнении запроса. Наше приложение открывает множество ResultSets и выбирает только несколько строк из каждого. Каждый запрос выбирает около 100 тыс. Строк, но мы выбираем только около 50 (этого достаточно для заполнения страницы). Проблема в том, что каждый запрос после первого содержит паузу около 2 с, когда драйвер загружает все строки из предыдущего ResultSet во временное хранилище (память или диск), чтобы их можно было просмотреть позже. Поскольку у нас около 6 запросов в худших сценариях, будет пауза около 10 с, что делает приложение невосприимчивым к пользователю. Версия MSSQL - 2005.

Чтобы удалить такие паузы, мы попытались включить MARS (множественные активные результирующие наборы) через параметры строки подключения драйвера JDBC Microsoft (из-за отсутствия документации мы перепробовали все, что перечислено в https://sites.google.com/site/sqlconnect/sql2005strings). Пример строки подключения:

JDBC: SQLServer: // TESTDBMACHINE; имя_экземпляр = S2005, Databasename = SampleDB; MarsConn = да

Но никто из них не решает проблему. Драйвер Microsoft JDBC, кажется, принимает что-либо в строке подключения - если вы замените MarsConn = yes на PleaseBeFast = yes, драйвер MS игнорирует параметр и даже не регистрирует факт. Я не знаю, является ли MARS клиентской функцией, которая просто кэширует строки из ранее активного набора результатов, или это серверная функция. Я даже не знаю, как определить на стороне сервера, использует ли данное соединение MARS. Если вы можете прокомментировать это, это будет приветствоваться.

Другим решением для паузы было использование прокручиваемых (двунаправленных) наборов результатов. Это удаляет паузу, но делает время выборки на 80% медленнее и потребляет больше ресурсов сети. Сейчас мы рассматриваем возможность реализации оболочки JDBC-соединений, которая поддерживает пул фактических соединений и автоматически выдает запросы к отдельным соединениям «ResultSet free». Но это несколько громоздко, потому что нам нужно сохранить связь между каждым соединением и его активным ResultSet. Кроме того, он потребляет больше соединений с сервера и может вызвать проблемы для администраторов баз данных. И это решение не помогает, если есть активная транзакция, для которой все запросы должны быть выполнены в одном соединении.

Знаете ли вы какой-либо параметр, конфигурацию, конкретный API, ссылку или трюк, которые могут убрать паузу во втором и последующих выполнениях запроса?

Ответы [ 3 ]

1 голос
/ 01 сентября 2011

исправьте ваши запросы SQL! зачем использовать только первые 50 или около того из 100 тыс. Строк ??используйте TOP 100 или что-то в этом роде!Нет никаких причин, по которым приложение должно фильтровать 100 тыс. Строк, это работа базы данных.

0 голосов
/ 16 сентября 2011

Мы создали источник данных ODBC с помощью драйвера SQL Server (собственный клиент 10 - sqlncli10.dll).Этот источник данных ODBC был настроен на включение MARS (ключ HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\ <em>datasource</em>, значение MARS_Connection должно быть Yes).Затем мы использовали мост Sun JDBC-ODBC, и вуаля!Паузы пропали, и, что удивительно, время выборки стало быстрее, чем драйверы JDBC для чистой JTDS и MSSQL!

Согласно http://msdn.microsoft.com/en-us/library/ms345109(SQL.90).aspx, MARS - это функция сервера.Чистые драйверы Java (от JTDS и MSSQL), похоже, не поддерживают MARS на основе обслуживания (по крайней мере, мы не смогли включить его после многих изменений конфигурации).Поскольку большая часть нашей пользовательской базы, использующей MSSQL Server, работает на Windows (что неудивительно), мы собираемся перейти с JTDS на JDBC-ODBC.Драйвер ODBC для собственного клиента и мост JDBC-ODBC представляются зрелыми, полнофункциональными и современными решениями, поэтому, думаю, проблем быть не должно.Если вы знаете что-то, пожалуйста, прокомментируйте!

Пользователи на базе Linux по-прежнему будут использовать JTDS.Поскольку теперь мы знаем, что MARS является серверной функцией, мы заполним запрос на поддержку JTDS и Microsoft для поддержки MARS в своих чистых драйверах JDBC Java.

0 голосов
/ 01 сентября 2011

Гораздо важнее, что беда вашего клиента - это то, что происходит на стороне сервера.Так как вы выдаете запросы, а затем перестаете читать результат, серверу придется приостановить запрос в середине выполнения, поскольку сетевые буферы заполнены и у них нет места для записи результата.Запрос, приостановленный в середине выполнения, потребляет много ресурсов: память, блокировки и, что наиболее важно, рабочий поток (существует очень несколько из них валяется).

Выпуск запросов только для необходимых данных, использование всех данных, освобождение соединения и, что более важно, ресурсов сервера.Если ваши запросы сложны, вернитесь к чертежной доске и перепроектируйте модель данных, чтобы правильно и эффективно отвечать на запросы, которые вы запрашиваете у нее.Прямо сейчас вы полностью лаете не на то дерево, а просто спрашиваете, как усугубить плохую ситуацию.

...