Шаг 1. Убедитесь, что SQL Server вызывает высокий ЦП
Используйте один из следующих средств, чтобы проверить, действительно ли SQL Server способствует высокому ЦП:
-
Диспетчер задач (На вкладке Process проверьте, близко ли значение ЦП для SQL Server Windows NT-64 Bit близко к 100 процентам)
-
Производительность и монитор ресурсов(perfmon)
- Счетчик: ,
- Пример: sqlservr
-
Для сбора встречных данных в течение 60 сек можно использовать следующий скрипт Powershell:
Если вы заметите, что процент последовательно превышает 90 процентов, это подтвердит, что SQL Server вызывает высокий ЦП. Однако, если вы заметите, что постоянно превышает 90 процентов, это указывает на то, что антивирусное программное обеспечение или другие драйверы или другой компонент ОС на компьютере способствуют высокому ЦП. Необходимо работать с системным администратором для анализа первопричин этого поведения.
Шаг 5. Изучение проблем, чувствительных к параметрам
Используйте команду DBCC FREEPROCCACHE, чтобы проверить, устранена ли проблема с высоким уровнем использования ЦП.
Если проблема еще существует, вы можете добавить подсказку запроса к каждому из высоких запросов ЦП, которые определены в .
Если проблема устранена, это указывает на проблему, чувствительную к параметрам (PSP, ака «проблема нюхания параметров»). Чтобы устранить проблемы, чувствительные к параметрам, используйте следующие методы. Каждый метод имеет связанные компромиссы и недостатки.
-
Используйте при каждом выполнении запроса. Это обходное решение балансирует время компиляции и увеличивает ЦП для улучшения качества планирования. Вот пример того, как это можно применить к запросу.
-
Чтобы переопредить фактическое значение параметра с типичным значением параметра, которое создает план, достаточно хороший для большинства возможностей параметра, используйте подсказку параметра Этот параметр требует полного понимания оптимальных значений параметров и связанных с ними характеристик плана. Вот пример использования этого подсказки в запросе.
-
Чтобы переопредить фактическое значение параметра со средним вектором плотности, используйте подсказку параметра Это также можно сделать, захватив входящие значения параметров в локальных переменных, а затем используя локальные переменные в предикатах, а не используя сами параметры. Для этого исправления средняя плотность должна быть достаточно высокой.
-
Используйте запроса, чтобы полностью отключить нюхание параметров. Вот пример использования его в запросе:
-
Используйте чтобы предотвратить перекомпилирование в кэше. Этот обход предполагает, что общий план «достаточно хорош» — это тот, который уже находится в кэше. Вы также можете отключить автоматические обновления статистики, чтобы уменьшить вероятность того, что хороший план будет выселен и будет составлен новый плохой план.
-
Использование команды DBCC FREEPROCCACHE является временным решением до тех пор, пока код приложения не будет исправлен. Вы можете использовать команду, чтобы удалить только план, который вызывает проблему. Например, чтобы найти планы запросов, ссылаясь на таблицу Person.Person в AdventureWorks, этот запрос можно использовать для поиска ручки запроса. Затем можно освободить определенный план запроса из кэша с помощью выпускаемого во втором столбце результата запроса.
Основы работы с ODBC API
Прежде чем перейти к проблеме организации эффективного ввода-вывода, давайте рассмотрим основные этапы работы с ODBC API. Для доступа к данным при помощи ODBC любая программа вызывает API-функции, причем в определённой последовательности:
- подключение к источнику данных;
- инициализация и настройка параметров SQL-запроса/оператора;
- формирование и выполнение запроса/оператора;
- получение результатов;
- отключение от источника данных.
Для соединения с источником данных с помощью функции SQLAllocHandle следует создать «хэндлы» для среды (environment) и соединения (connection).
ПРИМЕЧАНИЕ
Объявления ODBC-функций и констант находятся в файлах sql.h и sqlext.h, библиотечный файл – odbc32.lib. |
Необходимо также указать, что работать мы будем с третьей версией ODBC API. Затем можно подключиться к источнику данных функцией SQLConnect. Этой функции передаются имя источника данных (Data Source Name, DSN), имя пользователя (login), пароль (password) и длины этих строк.
Для строк языка С, которые заканчиваются нулём, можно передавать константу SQL_NTS (Null-Terminated String). |
DSN – обязательный параметр, без которого дальнейшая работа программы невозможна. Обычно DSN создают при установке приложения. Например, инсталлятор InstallShield легко справляется с этой задачей, также он устанавливает необходимые ODBC-драйверы.
В этом месте стоит упомянуть о возможности создания «на лету» имени для источника данных (DSN). Функция SQLConfigDataSource позволяет программным путём создать DSN и избавляет конечного пользователя от процесса настройки DSN. |
Все последующие этапы связаны с подготовкой и выполнением SQL-запросов. Для выполнения запроса требуется хэндл, который можно получить с помощью функции SQLAllocHandle. Далее может следовать так называемый прямой запрос, который выполняет функция SQLExecDirect, а может – сложный. В последнем случае запрос сначала подготавливается с помощью SQLPrepare, затем для передачи исходных данных или установки связи между переменными и параметрами SQL-оператора применяется функция SQLBindParameter. Когда всё готово для выполнения запроса, вызывают функцию SQLExecute. Для чтения данных обычно используют пару функций SQLFetch и SQLGetData, хотя существуют и другие способы. Например, для быстрого чтения данных из таблиц используют SQLBindCol. По окончании работы с запросом ресурсы следует освободить функцией SQLFreeHandle. Нужно не забыть отключиться от источника данных (функция SQLDisconnect) и освободить все ресурсы (функция SQLFreeHandle).
Всегда следует проверять значения, которые возвращают функции ODBC API. Функции в случае успешного выполнения возвращают значения SQL_SUCCESS или SQL_SUCCESS_WITH_INFO. Для того чтобы не выполнять две операции сравнения, существует удобный макрос SQL_SUCCEEDED.
Рисунок 1. Таблица users в базе данных
Проиллюстрируем работу с ODBC API на примере добавления записи в таблицу. Пусть у нас имеется таблица users. Эту таблицу мы будем использовать и для других примеров. В таблице три поля – идентификатор (номер) пользователя, его имя (name) и величина зарплаты (salary). В таблице используются поля трёх наиболее часто используемых типов – целое число, строка символов и число с плавающей точкой.
SQLHANDLE hEnv, hDbc; SQLRETURN res; // --== ИНИЦИАЛИЗАЦИЯ СОЕДИНЕНИЯ С БД ЧЕРЕЗ ODBC ==-- // Получаем хэндл ODBC-среды. res = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv); if( !SQL_SUCCEEDED(res) ) return -1; // Запрашиваем третью версию. SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); // Получаем хэндл для соединения. SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc); // Подключаемся к источнику данных. res = SQLConnect(hDbc, "Sample_DB", SQL_NTS, "", SQL_NTS, "", SQL_NTS); if( SQL_SUCCEEDED(res) ) { // --== ВЫПОЛНЕНИЕ SQL-ЗАПРОСА ==-- SQLHSTMT hStmt; // SQL-оператор для добавления записи в БД. SQLCHAR szSQL[]="INSERT INTO users (id, name, salary) VALUES (1, 'Bill', 100);"; // Получаем хэндл для SQL-запроса/оператора. SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt); // Простейший прямой SQL-запрос/оператор. SQLExecDirect(hStmt, szSQL, SQL_NTS); // Освобождаем ресурсы. SQLFreeHandle(SQL_HANDLE_DBC, hDbc); } // --== ЗАВЕРШЕНИЕ РАБОТЫ С ODBC ==-- // Отключаемся от источника данных. SQLDisconnect(hDbc); // Освобождаем ресурсы. SQLFreeHandle(SQL_HANDLE_DBC, hDbc); SQLFreeHandle(SQL_HANDLE_ENV, hEnv); |
Связанные представления, функции и процедуры
Просматривать хранилище запросов и управлять им можно с помощью Среда Management Studio или следующих представлений и процедур.
Хранимые процедуры в хранилище запросов
Хранимые процедуры служат для настройки хранилища запросов.
1 В чрезвычайных ситуациях хранилище запросов может перейти в состояние ERROR (Ошибка) из-за внутренних ошибок. Начиная с версии SQL Server 2017 (14.x), в таких случаях хранилище запросов можно восстановить, выполнив хранимую процедуру в соответствующей базе данных. Дополнительные сведения приведены в описании для столбца в статье sys.database_query_store_options.
Советы по использованию временных таблиц и табличных переменных
Если вы замечаете, что обращаетесь к одной и той же таблице несколько раз, то это явный знак необходимости использовать временную таблицу.
- Временная таблица храниться физически в tempdb, табличная переменная хранится в памяти SQL
- SQL может сам решить сохранить табличную переменную физически, если там будет много данных, это потеря ресурсов, учтите это
- Временная таблица для большого объема данных (полноценная выборка), табличная переменная для малого (справочники или набор ID для чего-то)
- Временная таблица доступна из любой процедуры SQL, табличная переменная только в рамках запроса. Не забывайте очищать временные таблицы после их использования
Кэшированные экземпляры
Кэшируемый экземпляр отчета основан на промежуточном формате отчета. Сервер отчетов в целом кэширует только один экземпляр отчета на основе его имени. Однако если отчет может содержать данные, зависящие от параметров запроса, то могут кэшироваться несколько версий отчета в любое данное время. Например, предположим, что имеется параметризованный отчет, который рассматривает код области в качестве значения параметра. Если у четырех различных пользователей имеются четыре уникальных кода области, то создаются четыре кэшированных копии.
Первый пользователь, который выполняет отчет с уникальным кодом области, создает кэшируемый отчет, который содержит данные для той области. Последующие пользователи, которые запрашивают отчет, используя тот же самый код области, получают его кэшированную копию.
Не все отчеты могут кэшироваться. Если отчет содержит данные, зависимые от пользователей, запрашивает у пользователей учетные данные или использует проверку подлинности Windows, то отчет не может быть кэширован.
4 ответа
31
Лично для общего запроса больше 2-го и последующих исполнений.
Проверяете ли вы производительность ввода-вывода на IO или производительность запроса?
Предполагая, что ваш запрос выполняется часто и имеет решающее значение, вы хотите измерить его в реальных условиях жизни. И вы не хотите каждый раз очищать кеш-файлы prod-сервера каждый раз …
Если вы хотите, вы можете:
-
очищает (немодифицированные) страницы из пула буферов
Предположим, что с сначала очистить все грязные страницы на диск - очищает планы выполнения для этой базы данных
Также см. (на DBA.SE)
Решение проблемы загрузки страницы с использованием SQL Profiler
8
Поздний ответ, но может быть полезен другим читателям
DBCC DROPCLEANBUFFERS — часто используемая команда для тестирования запросов и измерения скорости выполнения запросов. Эта команда (при запуске) оставляет только грязные страницы, на самом деле это небольшая часть данных. Он удаляет все чистые страницы для всего сервера.
Обратите внимание, что эта команда должна выполняться not в рабочей среде. Запуск этой команды приведет в основном к пусту буферного кеша
Выполняя любой запрос после выполнения команды DBCC DROPCLEANBUFFERS, будут использовать физические чтения для возврата данных в кеш, что, скорее всего, будет намного медленнее, чем память.
Снова, обработайте эту команду аналогично DBCC FREEPROCCACHE — ее нельзя запускать на каком-либо производственном сервере, если вы не знаете, что делаете.
Это может быть полезным инструментом разработки, поскольку вы можете запускать запрос в среде тестирования производительности многократно без каких-либо изменений в скорости /эффективности из-за кэширования данных в памяти.
Узнайте больше: http: //www.sqlshack .com /понимание-в-The-SQL-сервер-буфер кэш /
7
Мне всегда говорили использовать:
Из MSDN :
1
Другие ответы правильны о причинах not run . Однако для этого есть несколько причин:
- Согласованность
Если вы хотите сравнить два разных запроса или процедуры, которые пытаются сделать одно и то же по-разному, они, вероятно, попадут на одни и те же страницы. Если вы наивно запускаете запрос №1, тогда запрос №2, второй может быть намного быстрее, потому что эти страницы были кэшированы первым запросом. Если вы очищаете кеш перед каждым исполнением, они начинаются с четной основы.
Если вы хотите проверить производительность «горячего кеша», обязательно запускайте запросы несколько раз, чередуя и отбрасывая первые пару прогонов. Средние результаты.
- Наихудшая производительность
Скажите, что у вас есть запрос, который занимает одну секунду против горячего кеша, но одна минута против холодного кеша. Оптимизация, которая делает запрос в памяти на 20% медленнее, но запрос с привязкой к IO на 20% быстрее может быть большой победой: во время обычных операций никто не заметит дополнительные 200 мс при нормальных обстоятельствах, но если что-то заставляет запрос работать с диском, за 48 секунд вместо 60 может сохранить продажу.
Это меньше беспокоит современные системы с десятками гигабайт памяти и относительно быстрые SAN и SSD-хранилища, но это все еще имеет значение. Если какой-то аналитик проводит массивный запрос сканирования таблицы к вашей базе данных OLTP, которая уничтожает половину вашего кеша буфера, эффективные с точки зрения хранения запросы помогут вам быстрее вернуться к скорости.
Компонент Client Query Result Cache
В случае использования каких-нибудь приложений OCI или драйверов вроде JDBC или ODP.NET, можно применять предлагаемый Oracle механизм кэширования наборов результатов SQL-запросов на стороне клиентов, предусматривающий помещение результатов в компонент Client Query Result Cache (Кэш результатов клиентских запросов), который размещается на сервере. В таком случае база данных поддерживает наборы результатов в соответствующем изменениям в атрибутах сеансов состоянии. При наличии часто повторяющихся операторов в приложениях кэширование на стороне клиента может приводить к получению значительных преимуществ в плане скорости выполнения запросов. Из-за кэширования результатов базой данных на стороне клиентов, количество круговых обменов с сервером сводится к минимуму, благодаря чему улучшается масштабируемость и снижается нагрузка на подсистему ввода-вывода и ЦП.
В отличие от механизма кэширования на стороне сервера, механизм кэширования на стороне клиентов по умолчанию не включен. Если приложения производят небольшие наборы результатов, которые остаются статическими на протяжении какого-то времени, реализация механизма кэширования на стороне клиентов может оказаться довольно выгодным решением. Часто выполняемые запросы и запросы, задействующие справочные таблицы (lookup tables), тоже могут являться хорошими кандидатами на кэширование на стороне клиентов.
Включение и отключение компонента Client Query Result Cache
Как и для механизма кэширования на стороне сервера, для включения и отключения механизма кэширования на стороне клиентов применяется параметр инициализации RESULT_CACHE_MODE. Подсказки RESULT_CACHE и NO_RESULT_CACHE тоже работают тем же самым образом, что и при выполнении кэширования на стороне сервера. В случае указания значения MANUAL для параметра RESULT_CACHE_MODE, для того, чтобы результаты запроса кэшировались, нужно обязательно включить в него подсказку RESULT_CACHE. Кроме того, как и в случае кэширования на стороне сервера, обе эти подсказки переопределяют значение параметра RESULT_CACHE_MODE. Передавать подсказки RESULT_CACHE и NO_RESULT_CACHE операторам SQL, правда, нужно с помощью вызовов OCIStatementPrepare() и OCIStatementPrepare2().
Управление компонентом Client Query Result Cache
Управлять тем, как работает компонент Client Query Result Cache, позволяют два параметра. Ниже приведено их краткое описание.
CLIENT_RESULT_CACHE_SIZE. Этот параметр позволяет задавать максимальный размер клиентского кэша наборов результатов для каждого процесса (в байтах). Установка для него нулевого значения приводит к отключению Client Query Result Cache. По умолчанию база данных выделяет каждому клиентскому процессу OCI максимальный объем памяти.
Совет. Значение параметра CLIENT_RESULT_CACHE_SIZE можно переопределять с помощью серверного параметра OCI_RESULT_CACHE_MAX_SIZE. Например, установкой для него нулевого значения можно полностью отключить компонент Client Query Result Cache.
Еще есть необязательный клиентский конфигурационный файл, который переопределяет любые из касающихся кэширования на стороне клиента параметров, которые устанавливаются на сервере. Называется он sqlnet.ora, и в нем можно устанавливать следующие конфигурационные параметры на стороне клиента.
- OCI_RESULT_CACHE_MAX_SIZE. Этот параметр позволяет указывать максимальный размер кэша запросов для одного процесса.
- OCI_RESULT_CACHE_MAX_RSET_SIZE. Этот параметр позволяет задавать максимальный размер одного результата в байтах для одного процесса.
- OCI_RESULT_CACHE_MAX_RST_ROWS. Этот параметр позволяет указывать максимальный размер результата запроса в строках для одного процесса.
Также в приложениях OCI можно применять подсказки RESULT_CACHE и NO_RESULT_CACHE. С помощью представления CLIENT_RESULT_CACHE можно просматривать параметры кэша результатов и статистику использования Client Query Result Cache.
Ограничения
Ниже перечислены запросы, результаты которых нельзя помещать в кэш на стороне клиенте, хотя их возможно помещать в кэш результатов на стороне сервера:
- запросы к представлениям;
- запросы к удаленным объектам;
- запросы со сложными типами в списке выбора;
- запросы Flashback;
- запросы, включающие в себя PL/SQL-функции;
- запросы, ссылающиеся на VDP-политики таблиц.
Аргументы
( { plan_handle | sql_handle | pool_name } )plan_handle уникально идентифицирует план запроса для запущенного пакета, план которого хранится в кэше планов. Аргумент plan_handle имеет тип varbinary(64), и его можно получить из следующих объектов DMO:
- sys.dm_exec_cached_plans
- sys.dm_exec_requests
- sys.dm_exec_query_memory_grants
- sys.dm_exec_query_stats
sql_handle представляет дескриптор SQL очищаемого пакета. Аргумент sql_handle имеет тип varbinary(64), и его можно получить из следующих объектов DMO:
- sys.dm_exec_query_stats
- sys.dm_exec_requests
- sys.dm_exec_cursors
- sys.dm_exec_xml_handles
- sys.dm_exec_query_memory_grants
pool_name представляет имя пула ресурсов Resource Governor. Аргумент pool_name имеет тип sysname и может быть получен с помощью запроса к динамическому административному представлению sys.dm_resource_governor_resource_pools.
Чтобы связать группу рабочей нагрузки Resource Governor с пулом ресурсов, запросите динамическое административное представление sys.dm_resource_governor_workload_groups. Чтобы получить сведения о группе рабочей нагрузки для сеанса, запросите динамическое административное представление sys.dm_exec_sessions.
WITH NO_INFOMSGS
Подавляет вывод всех информационных сообщений.
COMPUTE
Очистка кэша планов запросов в каждом вычислительном узле. Это значение по умолчанию.
ALL
Очистка кэша планов запросов в каждом вычислительном узле и в управляющем узле.
Примечание
Начиная с версии SQL Server 2016 (13.x);, для очистки кэша процедур (планов) для базы данных в области действия служит инструкция .
Обновление статистик
MS SQL Server строит план запроса на основании статистической информации о распределении значений в индексах и таблицах. Статистическая информация собирается на основании части (образца) данных и автоматически обновляется при изменении этих данных. Иногда этого оказывается недостаточно для того, что MS SQL Server стабильно строил наиболее оптимальный план выполнения всех запросов.
В этом случае возможно проявление проблем с производительностью запросов. При этом в планах запросов наблюдаются характерные признаки неоптимальной работы (неоптимальные операции).
Для того, чтобы гарантировать максимально правильную работу оптимизатора MS SQL Server рекомендуется регулярно обновлять статистики базы данных MS SQL.
Для обновления статистик по всем таблицам базы данных необходимо выполнить следующий SQL запрос:
exec sp_msforeachtable N'UPDATE STATISTICS ? WITH FULLSCAN'
Обновление статистик не приводит к блокировке таблиц, и не будет мешать работе других пользователей. Статистика может обновляться настолько часто, насколько это необходимо. Следует учитывать, что нагрузка на сервер СУБД во время обновления статистик возрастет, что может негативно сказаться на общей производительности системы.
Оптимальная частота обновления статистик зависит от величины и характера нагрузки на систему и определяется экспериментальным путем. Рекомендуется обновлять статистики не реже одного раза в день.
Приведенный выше запрос обновляет статистики для всех таблиц базы данных. В реально работающей системе разные таблицы требуют различной частоты обновления статистик. Путем анализа планов запроса можно установить, какие таблицы больше других нуждаются в частом обновлении статистик, и настроить две (или более) различных регламентных процедуры: для часто обновляемых таблиц и для всех остальных таблиц. Такой подход позволит существенно снизить время обновления статистик и влияние процесса обновления статистики на работу системы в целом.
Настройка автоматического обновления статистик (MS SQL 2005)
Запустите MS SQL Server Management Studio и подключитесь к серверу СУБД. Откройте папку Management и создайте новый план обслуживания:
Создайте субплан (Add Subplan) и назовите его «Обновление статистик». Добавьте в него задачу Update Statistics Task из панели задач:
Настройте расписание обновления статистик. Рекомендуется обновлять статистики не реже одного раза в день. При необходимости частота обновления статистик может быть увеличена.
Настройте параметры задачи. Для этого следует два раза кликнуть на задачу в правом нижнем углу окна. В появившейся форме укажите имя базу данных (или несколько баз данных) для которых будет выполняться обновление статистик. Кроме этого вы можете указать для каких таблиц обновлять статистики (если точно неизвестно, какие таблицы требуется указать, то устанавливайте значение All).
Обновление статистик необходимо проводить с включенной опцией Full Scan.
Сохраните созданный план. При наступлении указанного в расписании срока обновление статистик будет запущено автоматически.
Рекомендуемые действия
Вы можете запретить операционной системе Windows выгружать на диск память буферного пула процесса SQL Server, заблокировав выделенную для этого буферного пула часть физической памяти. Чтобы заблокировать память, назначьте право «Блокировка страниц в памяти» учетной записи пользователя, которая используется в качестве стартовой учетной записи для службы SQL Server. Прежде чем воплощать в жизнь это решение, ознакомьтесь с разделами и «Важные аспекты, которые нужно учесть перед назначением пользователю прав на блокировку страниц в памяти» для экземпляра SQL Server.
Примечание
Использование блокировки страниц в памяти гарантирует, что управляемая SQL Server память не будет выгружаться на диск. Однако стеки потоков, EXE-файлы и любые библиотеки DLL, память кучи и память CLR могут вытесняться из памяти операционной системой.
Начиная с SQL Server 2008 с пакетом обновления 1 (SP1) и накопительным обновлением 2, выпуски SQL Server Standard и Enterprise поддерживают применение права пользователя на блокировку страниц в памяти. Дополнительные сведения о поддержке блокировки страниц см. в статье базы знаний KB970070 — Поддержка заблокированных страниц в системах SQL Server Standard Edition (64-разрядных).
Чтобы назначить право пользователя «Блокировка страниц в памяти», выполните следующие действия:
- Нажмите кнопку Пуск, выберите команду Выполнить, введите gpedit.msc и щелкните ОК.
- Откроется диалоговое окно «Групповая политика».
- Последовательно разверните узлы Конфигурация компьютера и Параметры Windows.
- Разверните узлы Настройки безопасности и Локальные политики.
- Щелкните «Назначение прав пользователя», а затем дважды щелкните Блокировка страниц в памяти.
- В диалоговом окне Параметры локальной политики безопасности щелкните Добавить пользователя или Группа.
- В диалоговом окне Выберите пользователей или Группы добавьте учетную запись, у которой есть разрешение на запуск файла Sqlservr.exe, а затем щелкните ОК.
- Закройте диалоговое окно Групповая политика.
- Перезапустите службу SQL Server .
После того, как вы назначите пользователю право «Блокировка страниц в памяти» и перезапустите службу SQL Server, операционная система Windows не будет выгружать на диск память буферного пула в процессе SQL Server. Но операционная система Windows сохранит возможность выгружать на диск память процесса SQL Server из небуферного пула.
Это сообщение применимо только к SQL Server. Дополнительные сведения об этом сообщении в журнале ошибок см. в следующей статье: Нужно ли присваивать разрешение «Блокировка страниц в памяти» в локальной системе?
Хотя операционная система Windows выгружает на диск память из небуферного пула, все равно могут возникать проблемы с производительностью. Но при этом в журнале ошибок SQL Server не регистрируются сообщения об ошибках, упомянутые в разделе «Объяснение».
Конфигурация дисков / Best Practices
Как правило, для повышения производительности, файлы журналов кладут на отдельные физические диски, а файлы данных размещают на других физических дисках. Ввод-вывод для высоко нагруженных файлов данных (включая tempDB) носит случайный характер. Ввод-вывод для файла журнала транзакций носит последовательный характер, кроме случаев отката транзакций. Встроенные в шасси сервера (локальные) диски можно использовать только для файлов журнала транзакций, потому что они хорошо ведут себя при последовательном вводе-выводе, а при случайном вводе-выводе ведут себя плохо. Файлы данных и журналов должны размещаться на разных дисковых массивах, у которых используются разные наборы физических дисков. В большинстве случаев, когда решение должно укладываться в не большой бюджет, я рекомендую размещать файл журнала транзакций на массиве RAID1, собранном из локальных дисков. Файлы данных БД лучше разместить на внешней системе хранения в сети SAN, так, чтобы к используемым для данных физическим дискам доступ получал только SQL Server, что позволит контролировать обслуживание его запросов и получать достоверные отчёты загрузки дисковой подсистемы. От подключения дисковых подсистем напрямую к серверу лучше отказаться. Кэширование записи должно быть включено везде, где только это возможно, и вы должны удостовериться, что кэш защищен от перебоев в питании и других возможных отказов (независимая батарея подпитки кэша на контроллере). Во избежание появления узких мест ввода-вывода для OLTP систем, лучше не смешивать нагрузки, характерные для OLTP и OLAP. Кроме того, удостоверьтесь, что серверный код оптимизирован и, где это необходимо, созданы индексы, которые тоже позволяют избавиться от ненужного ввода-вывода.