Большой объем записи журнала tempdb, без чтения
Я сталкиваюсь с некоторым поведением, которое кажется мне странным. Я использую SQL Server 2008 Enterprise, 32-разрядный (Quad Core 2), на Windows 7 (для тестирования).
У меня есть хранимая процедура, которая использует две табличные переменные. Один получает около 2 или 3 строк, другой получает от 0 до 100 строк. Затем я выбираю, может быть, 20-60 строк из второго, и все.
Производительность довольно быстрая. Я создал простое приложение для цикла выполнения запросов, и я могу делать 1300/ сек с 1 потоком и около 4000 с 4 потоками.
Введите tempdb: Когда я открываю монитор ресурсов, чтобы посмотреть, что происходит, я вижу, что в файлы журналов tempdb идет много записи. (Я создал 2, 100 МБ на 2 разных физических дисках - они, кажется, не превышают 100 МБ.) Нет активности чтения - вся БД помещается в ОЗУ.
Если в одном потоке выполняются запросы, скорость записи в файлы журнала tempdb составляет около 3 МБ / с. Когда я увеличиваю это, оно увеличивается до 20 МБ / с на файл журнала.
В мониторе активности SQL "Ведение журнала" идет более 300 мс / с для "Время ожидания", когда я использую 5 потоков. При 3 потоках скорость снижается до 25 мсек / с.
Вопрос: что происходит? Почему SQL пишет в журналы tempdb как сумасшедшие, но выдает нулевое чтение (я не вижу активности чтения в мониторе ресурсов или в мониторе активности)? В не тестовой среде мне кажется, что наличие дополнительной записи 40 МБ / с может отрицательно сказаться на общей производительности.
Я знаю, что переменные таблицы (@foo) не всегда хранятся в памяти, но я не понимаю, почему tempdb должен регистрировать все эти вещи. Как я могу решить, что он делает? Могу ли я поместить журнал tempdb на виртуальный диск или что-то? Любые другие указатели?
Заранее спасибо!
1 ответ
Это типичное поведение при записи в журнал. Когда страница обновляется в базе данных, обновление сначала записывается в журнал, а затем применяется к странице в памяти. Страница остается грязной в памяти до тех пор, пока не появится контрольная точка, после чего она будет записана на диск. Журнал должен быть записан перед обновлением для поддержки восстановления и отката. Если не произойдет одно из этих двух событий (восстановление или откат), нет необходимости когда-либо снова читать журнал. Таким образом, поведение, которое вы видите, типично для системы, которая изменяет страницы в базе данных tempdb. Вы увидите только чтение журнала, если произойдет откат (так как восстановление не может быть выполнено для базы данных tempdb).
Более интересный вопрос: почему в tempdb происходит так много обновлений страниц? Типичными виновниками являются либо прямые обновления (например, состояние сеанса в базе данных tempdb с ASP), либо косвенные (спули и сортировки в планах запросов).