SQL Server 2005: повышение производительности для тысяч или запросов на вставку. время выхода из системы - 120 мс - PullRequest
0 голосов
/ 14 января 2010

Может кто-нибудь пролить свет на то, как работает SQL Server 2005, может ли запрос, выданный клиентом с использованием ADO.NET 2.0. Ниже приведен краткий вывод SQL Trace. Я вижу, что пул соединений работает (я считаю, что в пуле только одно соединение). Что мне не понятно, так это то, почему у нас так много вызовов sp_reset_connection, то есть серии: Аудит входа в систему, SQL: BatchStarting, RPC: запуск и аудит выхода из системы для каждого цикла for ниже. Я вижу постоянное переключение между базой данных tempdb и базой данных, что позволяет мне сделать вывод, что мы потеряли контекст при создании следующего соединения, выбрав его из пула на основе аргумента ConectionString.

Я вижу, что каждые 15 мс я могу получать 100-200 входов / выходов в секунду (в то же время сообщается Профилировщиком). Через 15 мс я снова получаю серию 100-200 входов / выходов в секунду.

Мне нужно уточнить, как это может повлиять на очень сложные запросы вставки в производственной среде. Я использую Enterprise Library 2006, код скомпилирован с VS 2005, и это консольное приложение, которое анализирует плоский файл с 10 тысячами строк, группирующих строки типа «родитель-потомок», запускается на сервере приложений и запускает 2 хранимые процедуры на удаленном SQL. Сервер 2005, вставляющий родительскую запись, извлекает значение Identity и, используя его, вызывает вторую хранимую процедуру 1, 2 или несколько раз (иногда несколько тысяч), вставляя дочерние записи. Дочерняя таблица содержит около 10 миллионов записей с 5-10 индексами, некоторые из которых охватывают некластеризованные. Существует довольно сложный триггер вставки, который копирует вставленную подробную запись в архивную таблицу. В целом у меня всего 7 вставок в секунду, а это означает, что для 50 тысяч записей может потребоваться 2-4 часа. Когда я запускаю Profiler на тестовом сервере (это почти эквивалентно производственному серверу), я вижу, что между записями трассировки Audit Logout и Audit Login примерно 120 мс, что почти дает мне возможность вставить около 8 записей.

Итак, мой вопрос: есть ли какой-то способ улучшить вставку записей, поскольку компания загружает 100 тысяч записей и выполняет ежедневное планирование, а также имеет SLA для выполнения запросов клиентов в виде плоских заказов, а некоторые большие файлы> 10 тысяч должны быть обработано (импортировано быстро). 4 часа на импорт 60 тысяч следует сократить до 30 минут.

Я думал использовать BatchSize для DataAdapter для отправки нескольких вызовов хранимых процедур, SQL Bulk вставляет для пакетной обработки нескольких вставок из DataReader или DataTable, SSIS быстрой загрузки. Но я не знаю, как правильно анализировать реиндексацию и статистику населения, и, возможно, это займет некоторое время, чтобы закончить. Хуже всего то, что компания использует самую большую таблицу для отчетности и другой онлайн-обработки, и индексы нельзя отбрасывать. Я управляю транзакцией вручную, устанавливая в поле значение и выполняю обновление транзакции, меняя это значение на новое значение, которое другие приложения используют для получения зафиксированных строк.

Посоветуйте, пожалуйста, как подойти к этой проблеме. На данный момент я пытаюсь иметь промежуточные таблицы с минимальным ведением журнала в отдельной базе данных и без индексов, и я попытаюсь сделать пакетные (массивные) родительские дочерние вставки. Я считаю, что у производственной БД простая модель восстановления, но это может быть полное восстановление. Если пользователь БД, который используется моим консольным приложением .NET, выполняет роль bulkadmin, это означает, что его массовые вставки минимально регистрируются. Я понимаю, что когда в таблице есть кластеризованные и многие некластеризованные индексы, вставки по-прежнему регистрируются для каждой строки.

Пул соединений работает, но со многими входами / выходами. Почему?

для (int i = 1; i <= 10000; i ++) { using (SqlConnection conn = new SqlConnection ("server = (local); база данных = master; встроенная защита = sspi;")) {Conn.Open (); using (SqlCommand cmd = conn.CreateCommand ()) { cmd.CommandText = "use tempdb"; cmd.ExecuteNonQuery ();}}} </p>

Трассировка SQL Server Profiler:

Аудит Мастер входа 2010-01-13 23: 18: 45.337 1 - Не пул
SQL: BatchStarting использует tempdb master 2010-01-13 23: 18: 45.337
RPC: запуск exec sp_reset_conn tempdb 2010-01-13 23: 18: 45.337
Выход из системы аудита tempdb 2010-01-13 23: 18: 45.337 2 - Пул
Аудит входа в систему - мастер сетевого протокола 2010-01-13 23: 18: 45.383 2 - Пул
SQL: BatchStarting использует tempdb master 2010-01-13 23: 18: 45.383
RPC: запуск exec sp_reset_conn tempdb 2010-01-13 23: 18: 45.383

Выход из системы аудита tempdb 2010-01-13 23: 18: 45.383 2 - Пул
Аудит входа в систему - мастер сетевого протокола 2010-01-13 23: 18: 45.383 2 - Пул
SQL: BatchStarting использует tempdb master 2010-01-13 23: 18: 45.383
RPC: запуск exec sp_reset_conn tempdb 2010-01-13 23: 18: 45.383
Выход из системы аудита tempdb 2010-01-13 23: 18: 45.383 2 - Пул

Ответы [ 2 ]

1 голос
/ 14 января 2010

Что вы подразумеваете под «записывать в лог-файлы». Вы имеете в виду, что мне нужно проанализировать плоский файл, выполнить локальные преобразования полей, выполнить некоторые вычисления на основе родительских и подробных строк и вывести их в файл с разделителями в файловой системе или в формате, ожидаемом FCP-файлом BCP и используйте Bulk Insert. Я думаю использовать любой из этих методов: Ускорьте копирование с помощью SqlBulkCopy на eggheadcafe.com

Модель производителя / потребителя http://sqlblog.com/blogs/alberto_ferrari/archive/2009/11/30/sqlbulkcopy-performance-analysis.aspx

Спасибо, Rad

0 голосов
/ 14 января 2010

Если у вас высокая среда вставки, и пользователю, запрашивающему вставку, не нужны никакие непосредственные данные, полученные в результате фактической вставки, я настоятельно рекомендую пакетировать вставки. Вместо того, чтобы позволить 200 разным пользователям одновременно пытаться вставить в одну и ту же таблицу, вы можете либо (а) записать в файлы журнала, а затем использовать BULK INSERT / BCP / SSIS для импорта данных с желаемой частотой (баланс как быстро данные должны быть отражены в базе данных, и насколько вы хотите, чтобы активность была), или (b) записать в несколько разных промежуточных таблиц, а затем снова округлить их с желаемой частотой. Оба (а) и (б) значительно облегчат спор; (a) немного лучше, потому что вы можете полностью отключить базу данных, и приложение все равно будет нормально работать.

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