![]() |
Технология Клиент-Сервер 2007'2 |
||||||
|
Представьте, что при очередном запуске приложения вы получили исключение 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-провайдеров данных должно получить эти данные при выборке, даже если приложение никогда не выводит эти длинные данные пользователю. Нужно попытаться реализовать метод, по возможности ограничивающий число выбираемых столбцов.
Copyright © 1994-2016 ООО "К-Пресс"