Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #52, МАРТ 2005 г.

Повышение производительности

Заратустра

Спецвыпуск: Хакер, номер #052, стр. 052-050-3


Основное заблуждение при разработке баз данных: для повышения производительности достаточно проиндексировать все возможные столбцы. Эти действия не только бесполезны, но и чреваты снижением производительности в несколько раз. Суть проблемы выбора индексов в том, что SQL-сервер должен изменять их при любых "реформах" в таблицах (INSERT, UPDATE, DELETE). Если индексов один или два, больших потерь производительности не будет. Но если их намного больше, SQL-сервер оказывается перегруженным работой с таблицами.

Другая проблема: после оптимизации запроса базой данных индекс может может стать неиспользуемым. Иногда SQL-серверу потребуется меньше времени на перебор таблицы, чем на использование индекса. Такие индексы служат балластом и, по-хорошему, должны быть удалены. Их можно отловить анализатором SQL-запросов, который даст полную картину обработки запросов.

В идеале весь код Transact-SQL, используемый в приложениях, должен находиться в хранимых процедурах, а не запускаться в виде динамического SQL или скриптов. Это уменьшает сетевой трафик (передается только CALL или EXECUTE) и ускоряет выполнение самого кода Transact-SQL, так как код в хранимых процедурах является прекомпилированным.

Но и тут тебя ждут подводные камни. Когда хранимая процедура выполняется в первый раз (и у нее не определена опция WITH RECOMPILE), она оптимизируется, для нее создается план выполнения запроса, который кешируется SQL-сервером. Если та же самая хранимая процедура вызывается снова, она будет использовать кешированный план выполнения запроса, что сэкономит время и увеличит производительность. Но если запрос динамический (изменяется от одного выполнения хранимой процедуры к другому), оптимизации не будет, а производительность только пострадает. Если известно, что запрос будет меняться каждый раз при выполнении хранимой процедуры, нужно добавить опцию WITH RECOMPILE, которая заставит перекомпилировать хранимую процедуру заново и оптимизировать запрос.

Другая неприятная особенность, с которой можно столкнуться, - блокировки (deadLock). Это тот случай, когда два процесса пытаются заблокировать два объекта, причем каждый процесс пытается заблокировать объект, который принадлежит другому процессу. В этом случае SQL-сервер прерывает один из процессов, откатывает его транзакцию, тем самым позволяя второму процессу продолжить работу. Этого можно избежать, если получать доступ к объектам в одном и том же порядке и не допускать пользовательского ввода во время транзакций. То есть получить все необходимые данные до начала транзакции.

Причиной падения производительности могут стать и триггеры. При их использовании придерживайся простых правил:

- Чем меньше код триггера, тем лучше и тем быстрее выполняются операции.

- Не используй триггеры для задач, которые могут быть реализованы другими, более эффективными способами. Например, для проверки значений лучше использовать CHECK, а не триггер.

Назад на стр. 052-050-2  Содержание  Вперед на стр. 052-050-4