Продолжается подписка на наши издания! Вы не забыли подписаться?

5 верных советов по производительности ADO.NET

Автор: Jonathan Bruce
Опубликовано: 06.12.2002
Версия текста: 1.0

Быстро написать код != написать быстрый код
Пользователям не нужно много данных
Правильно используйте DbCommand.Prepare()

Представьте, что при очередном запуске приложения вы получили исключение System.YourCodeIsRunningTooSlowException.

Такого исключения пока что не существует, но, возможно, неплохо бы Microsoft-у научиться как-то сигнализировать об основных узких местах при исполнении приложения. Это более важно в системах, где производительность и масштабируемость – вопрос общего успеха и применимости приложения. IT-организации вкладывают значительные ресурсы в оптимизацию и топологию сетей, а также дизайн БД для их приложений, но зачастую упускают аспекты производительности middleware. Разработчики упускают влияние ADO.NET-провайдера на приложение, несмотря на то, что существенная часть времени отклика - это время запроса и получения данных из БД.

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

Некоторые организации только реагируют на проблемы производительности и масштабирования, поскольку игнорируют этапы разработки и тестирования, необходимые для оптимизации приложения. Они просто разрабатывают приложение, а затем решают проблемы производительности по мере их поступления.

Куда лучше постараться приложить все необходимые усилия для того, чтобы ваше приложение отвечало ожиданиям пользователей, как в плане функциональности, так и в плане производительности. Да, неплохо было бы, если бы ваша система выдавала при работе исключение System.YourCodeIsRunningTooSlowException. Однако есть всего несколько шагов, позволяющих убедиться в эффективности работы приложения до его реального развертывания.

Одна из главных причин проблем с производительностью приложений, работающих с БД, состоит в том, что сложно разрабатывать быстрый .NET-код доступа к данным. Документация ADO.NET включает только основные принципы и определения интерфейсов, и не содержит почти ничего в смысле наставлений для разработчиков, стремящихся писать высокопроизводительный код.

Однако не отчаивайтесь. Вы можете предпринять действия, которые приведут к созданию более быстрого и надежного кода. Я покажу вам несколько распространенных ловушек, в которые, по моим наблюдениям, попадают многие и регулярно, - а также способ избежать их.

Быстро написать код != написать быстрый код

Многие программисты используют объект DbCommandBuilder, поскольку это ускоряет разработку приложений, использующих DataSet-ы. Однако это ускорение может отрицательно сказаться на производительности. Из-за встроенных ограничений параллелизма DbCommandBuilder может сгенерировать очень неэффективные SQL-выражения. Предположим, например, что у вас есть таблица EMP из восьми столбцов, хранящая сведения о работниках. Объект DbCommandBuilder сгенерирует такое выражение UPDATE:

CommandText: "UPDATE EMP SET EMPNO = ?, 
   ENAME = ?, JOB = ?, MGR = ?, HIREDATE = ?, 
   SAL = ?, COMM = ?, DEPT = ? WHERE ( (EMPNO 
   = ?) AND (ENAME = ?) AND (JOB = ?) AND 
   ((MGR IS NULL AND ? IS NULL) OR (MGR = ?)) 
   AND (HIREDATE = ?) AND (SAL = ?) AND 
   ((COMM IS NULL AND ? IS NULL) OR (COMM = 
   ?)) AND (DEPT = ?) )"

Вы можете написать куда более эффективные выражения UPDATE и DELETE, чем сгенерированные DbCommandBuilder. Допустим, например, что вы при работе с предыдущим примером знаете схему нижележащей БД. Предположим также, что вы знаете, что столбец EMPNO – первичный ключ таблицы EMP. Вы можете создать куда более простое выражение UPDATE, выдающее те же результаты:

UPDATE EMP SET EMPNO = ?, ENAME = ?, JOB = ?, 
   MGR = ?, HIREDATE = ?, SAL = ?, COMM = ?, 
   DEPT = ? WHERE EMPNO = ?

Это выражение исполняется гораздо эффективнее, чем сгенерированное DbCommandBuilder.

Еще один недостаток объекта DbCommandBuilder – он генерирует выражения во время исполнения. При каждом вызове метода DataAdapter.Update DbCommandBuilder анализирует содержимое набора результатов и генерирует выражения UPDATE, INSERT и DELETE для DataAdapter. Программист может избежать этой траты времени, явно указав выражения UPDATE, INSERT и DELETE для DataAdapter.

Еще один ключевой совет по производительности: исключите выборку BLOB-ов, если они вам не нужны. Получение длинных данных по сети – дело медленное и ресурсоемкое. Помните, что когда вы используете DataSet, все данные выбираются из источника данных, даже если вы их никогда не используете. Однако некоторые приложения не формируют списка выборки перед отправкой запроса .NET-провайдеру данных. Другими словами, некоторые приложения при отправке запроса используют такой синтаксис:

send SELECT * from <table name> ...

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

Пользователям не нужно много данных

Правильно используйте DbCommand.Prepare()


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

Copyright © 1994-2016 ООО "К-Пресс"