Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья

Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья

Наталия Елманова

Одним из основных причин, влияющих на принятие решения о переносе информационных систем в архитектуру клиент/сервер, является возможная возможность увеличения производительности работы юзеров, в особенности в тех случаях, когда находящиеся в эксплуатации приложения не удовлетворяют требованиям, предъявляемым к скорости обработки данных ввиду их огромного объема, также высочайшей интенсивности и Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья трудности запросов. Понятно, что информационные системы, основанные на архитектуре клиент/сервер, могут владеть существенными преимуществами перед информационными системами, базирующимися на сетевых версиях настольных СУБД, такими, как значительно наименьший сетевой трафик, наименьшее время обработки запросов, наименьшая ресурсоемкость клиентских приложений и наименьшие трудовые затраты при их разработке.

Но сам по Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья для себя факт переноса имеющейся базы данных из настольной СУБД на какой-нибудь сервер баз данных с соответственной корректировкой опций BDE (либо других средств доступа к данным) никак не гарантирует увеличения производительности информационной системы в целом. Представьте для себя, к примеру, базу данных, содержащую одну-единственную таблицу из Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья сотки записей и 5 целочисленных полей, содержащуюся в Oracle Workgroup Server, функционирующем под управлением Windows NT на компьютере с 16 Мб оперативки, и однопользовательское приложение, использующее навигационные способы для ее редактирования. В данном случае, непременно, проще хранить данные в таблице формата dBase либо Paradox - производительность системы будет в данном случае, вероятнее Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья всего, намного выше, потому что таковой сервер, как Oracle, просит сам по для себя много ресурсов, а объем обрабатываемых данных и разработка их обработки не оправдывают издержек, связанных с приобретением, установкой и эксплуатацией серверной СУБД такового класса. Данный пример, естественно, несколько утрирует реальную ситуацию, но время от времени на практике происходят и Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья поболее экзотичные случаи:

Итак, какие шаги необходимо сделать для того, чтоб вправду повысить эффективность работы юзеров и производительность системы в целом? Первым шагом в данном направлении является, естественно, выбор сервера. В данном случае, к огорчению, нельзя давать конкретных советов типа "возьмите Oracle, он надежен" либо "возьмите IB, он дешево Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья стоит". Выбор сервера, управляющей им операционной системы и соответственного аппаратного обеспечения должен осуществляться с учетом реальных и потенциально ожидаемых критерий эксплуатации системы, таких, как скорость роста объема данных (к примеру, в мб за месяц), интенсивность транзакций, возможность многопользовательского доступа к одной либо примыкающим записям в таблицах (при Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья высочайшей вероятности лучше избрать сервер, при использовании которого реально избежать страничных блокировок), возможный рост интенсивности работы юзеров, наличие завышенных требований к безопасности и защите данных (некие серверные СУБД выпускаются в различных исполнениях, отличающихся друг от друга степенью защищенности данных), необходимость использования товаров посторониих производителей (таких, как ODBC-драйверы Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья, дополнительные библиотеки и утилиты и др.), наличие связанных с этим заморочек (обычным примером из недавнешней реальной практики была, к примеру, неувязка поиска ODBC-драйвера к серверу Centura SQLBase 6.0, поддерживающего внедрение хранимых процедур). Более, чем технические, важны и денежные нюансы этой препядствия. Планируется ли использовать для установки серверной СУБД уже имеющеся Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья вычислительные мощности и операционную систему либо следует приобрести новые? В какую сумму обойдется приобретение серверной СУБД, клиентских лицензий, аппаратного обеспечения? Сколько будет стоить администрирование этой СУБД и управляющей ей операционной системы, также обучение будущих админов и программистов? Сколько подключений к серверу допускается при приобретении одной лицензии - одно, два, четыре Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья? Каковы условия, налагаемые лицензионными соглашениями при использовании мультиплексирования соединений за счет эксплуатации серверов приложений, если в предстоящем вероятен переход к трехзвенной архитектуре? Принятие решения о выборе серверной СУБД значительно находится в зависимости от ответа на все эти вопросы, и не всегда технические нюансы либо мировоззрение разработчиков определяют в Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья итоге выбор сервера. Нередки также случаи, когда подразумевается внедрение уже имеющейся в наличии серверной СУБД (либо даже готовой базы данных).

Представим, что сервер избран (исходя из вышеизложенных либо каких-то других суждений). Каким образом следует использовать предоставляемые им способности? Эффективность эксплуатации информационной системы исходя из убеждений производительности находится в зависимости от Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья согласованной работы 3-х ее составных частей - сервера баз данных, клиентского приложения и клиентской части серверной СУБД, функционирующих на рабочей станции, и сети, и неоптимальная работа одной из этих частей может свести к нулю итог всех усилий, направленных на оптимизацию работы других частей. Таким макаром, неувязка оптимизации работы информационной системы достигается Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья методом решения нескольких задач: оптимизации клиентской части, оптимизации серверной части, понижения сетевого трафика. Ниже мы разглядим некие приемы, содействующие в той либо другой степени решению этих задач. Но перед этим изучим один из простых методов контроля содержимого запросов, пересылаемых на сервер баз данных библиотекой BDE, и Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья результатов их выполнения, при помощи утилиты SQL Monitor, входящей в набор поставки С++Builder.

Контроль запросов при помощи SQL Monitor.

SQL Monitor употребляется для контроля запросов, пересылаемых клиентским приложением серверу баз данных средством BDE, и их результатов, также измерения времени меж ними. Для его пуска следует избрать пункт SQL Monitor Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья из меню Database C++Builder. Главное окно SQL Monitor состоит из 2-ух частей. В высшей части показываются поочередно генерируемые SQL-предложения и сведения об откликах сервера, также порядковый номер и время их пришествия, а в нижней части - полный текст SQL-запроса. Перечень, отображаемый в верхнем окне, можно сохранить в Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья файле для предстоящего анализа. На рис.1 представлен обычный вывод сведений при работе приложения, рассмотренного в предшествующей статье данного цикла.

При использовании SQL Monitor вероятен выбор типов отображаемых сведений. Их можно избрать в диалоге Trace Options, вызываемом из меню Options.

SQL Monitor позволяет показывать сведения о последующих действиях:

Prepared Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья Query Statements - SQL-предложения, передаваемые на сервер

Executed Query Statements - SQL-предложения, готовые к выполнению сервером

Statement Operations - деяния, выполняемые сервером (FETCH, EXECUTE и др.)

Connect/Disconnect - деяния, связанные с установкой либо разрывом соединения с сервером.

Transactions - деяния, связанные с выполнением транзакций (BEGIN, COMMIT, ROLLBACK)

Blob I/O - деяния, связанные Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья с передачей Blob-полей

Miscellaneous - другие деяния

Vendor Errors - сообщения об ошибках, возвращаемые сервером

Vendor Calls - вызовы функций API клиентской части, связанных с воззванием к серверу

Внедрение SQL Monitor является простым (хотя и не единственным) средством тестирования производительности информационных систем в архитектуре клиент/сервер, и эффективность внедрения большинства рассматриваемых ниже приемов Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья их оптимизации можно проконтролировать с его помощью.

Минимизация воззваний к серверу и сети

Минимизация связей с сервером оказывает влияние на производительность всех составных частей информационной системы - клиента, сервера и сети. Излишние связи с сервером приводят к созданию дополнительных объектов (таких, как TDatabase) в клиентском приложении, генерации дополнительных запросов Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья к серверу для выяснения прав юзера на доступ к тем либо другим объектам базы данных, также к непродуктивному использованию ресурсов сервера. Для минимизации связей с сервером можно использовать такие приемы, как внедрение в очевидном виде компонента TDatabase заместо неявного их сотворения, внедрение кэширования данных и структуры, хранение сведений о метаданных Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья в клиентском приложении, внедрение локальных фильтров и др.

Внедрение компонента TDatabase

При использовании нескольких компонент TDataSet следует подразумевать, что любой из их стремится во время выполнения сделать неявно собственный объект TDatabase для связи с сервером. Если же поместить компонент TDatabase на форму либо в модуль данных на шаге проектирования Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья приложения, и связать с ним все составляющие TDataSet, указав его имя в качестве значения характеристики DatabaseName этих компонент, они все будут использовать одну общую связь, обеспеченную этим компонентом.

Внедрение параметра SQLPASSTHRU MODE

Очередной метод минимизации связей с сервером заключается в изменении значения параметра SQLPASSTHRU MODE компонента TDatabase (или Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья псевдонима, сделанного утилитой конфигурации BDE). Этот параметр определяет, могут ли употребляться общие соединения с базой данных запросами, сгенерированными приложением (к примеру, при помощи компонента TQuery), и запросами, сгенерированными самой библиотекой BDE (к примеру, при реализации навигационных способов компонента TTable). Значением этого параметра по дефлоту является NOT SHARED, позволяющее Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья избежать вероятных конфликтов при многопользовательском обновлении данных, но создающее отдельные соединения с базой данных для обоих типов запросов.

Более действенным исходя из убеждений минимизации соединений с базой данных значением этого параметра почти всегда является значение SHARED AUTOCOMMIT. При использовании этого значения конфигурации каждой записи в таблицах немедля фиксируются сервером независимо Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья от типа вызвавшего их запроса, но при всем этом оба типа запросов могут использовать одно и то же соединение с базой данных. Этот режим более близок к режиму, в каком употребляются сетевые версии настольных СУБД. Но потому что сервер в данном случае должен немедля фиксировать результаты конфигурации Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья записей, он инициирует и завершает отдельную транзакцию при изменении каждой записи, что может привести к перегрузке сервера и сети и к понижению производительности заместо ожидаемого ее увеличения. Потому эффективность использования такового режима должна быть непременно испытана методом тестирования.

Третье вероятное значение этого параметра - SHARED NOAUTOCOMMIT. В данном случае оба типа запросов могут Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья также использовать одно и то же соединение с базой данных, при этом без окончания транзакций после редактирования каждой записи. Но в данном случае контроль за окончанием транзакций следует производить в клиентском приложении. Схожий режим может быть очень эффективен, потому что перегружающие сервер транзакции автоматом не инициируются Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья после редактирования каждой записи, но при его использовании могут появляться конфликты и непредсказуемые конфигурации данных при попытке одновременного редактирования одной и той же записи различными юзерами. Потому данный режим следует использовать исключительно в том случае, если возможность схожих коллизий мала.

Кэширование метаданных на рабочей станции

Очередной метод минимизации связей Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья с сервером заключается в использовании кэширования структуры таблиц на рабочей станции. В данном случае понижается число воззваний к серверу с целью определения метаданных, т.е. количества столбцов в применяемых в приложении таблицах, их имен и типов данных. Для этой цели употребляются последующие характеристики псевдонима базы данных (либо компонента TDatabase):

ENABLE SCHEMA Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья CACHE - разрешено ли кэширование метаданных;

SCHEMA CACHE SIZE - количество таблиц, структура которых кэшируется;

SCHEMA CACHE TIME - время хранения инфы в кэше в секундах; значение -1 соответствует времени хранения данных в кэше до закрытия приложения;

SCHEMA CACHE DIR - каталог для кэширования метаданных.

Применение кэширования метаданных может значительно повысить производительность Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья клиентских приложений и понизить нагрузку на сеть. Но использовать его можно исключительно в том случае, если структура таблиц не изменяется в течение работы приложения. Если же в процессе работы приложения делается добавление либо удаление столбцов, создание либо удаление индексов (не непременно тем же приложением), создание и удаление временных таблиц, информация Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья в кэше возможно окажется не соответственной реальности, что может привести к ошибкам, связанным с недопустимыми типами данных, недопустимыми преобразованиями типов и др. В данном случае использовать кэширование метаданных не рекомендуется.

Внедрение потомков TField в клиентском приложении

Другим методом хранения на рабочей станции приложении сведений о метаданных является внедрение компонент Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья - потомков TField. Потому что надлежащие объекты хранят сведения о структуре таблиц конкретно в приложении, на шаге выполнения не делается воззваний на сервер с целью получения метаданных. Внедрение потомков TField лучше, чем внедрение способов FieldByName() либо характеристики Fields, потому что последние употребляют воззвание к серверу для получения сведений о Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья типах полей. Ограничения на применение компонент - потомков TField такие же, как и в прошлом случае - их внедрение рекомендуется при размеренной структуре таблиц. Кроме этого, изменение структуры данных на сервере может востребовать модификации приложения и, как следствие, установку его новейшей версии на рабочие станции.

Кэширование данных на рабочей станции

Кроме кэширования метаданных Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья часто применяется и кэширование на рабочей станции самих данных. Для этой цели следует установить равным true значение характеристики CachedUpdates соответственного компонента TDataSet. В данном случае все внесенные юзером конфигурации сохраняются в локальном кэше. Сохранение данных на сервере делается при помощи способа ApplyUpdates() компонента TDataSet, а способ CommitUpdates() очищает кэш Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья. В целом таковой способ понижает сетевой трафик и суммарное число соединений с сервером, потому что, во-1-х, при редактировании данных в кэше не требуется наличия соединения с сервером, а во-2-х, сохранение нескольких записей из кэша на сервере может быть осуществлено методом выполнения одной-единственной транзакции. Кроме этого, понижается Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья суммарное число блокировок записей на сервере, потому что в процессе редактирования данных в кэше необходимости в блокировках нет.

Внедрение локальных фильтров при маленьких объемах данных

Если компонент TDataSet доставляет на рабочую станцию маленький по объему набор данных, сопоставимый с размером кэша рабочей станции (определяемого параметрами MINBUFSIZE и MAXBUFSIZE системных Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья опций BDE), он будет стопроцентно кэшироваться на рабочей станции. В данном случае применение локальных фильтров более желательно, чем внедрение запросов с предложением WHERE, направляемых на сервер, потому что в первом случае не требуется воззвание к серверу.

Оптимизация использования сервера

Внедрение хранимых процедур

При выполнении неоднократно циклических действий Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья, использующих данные с сервера (к примеру, при статистической обработке содержащихся в таблицах данных) производительность информационной системы можно повысить, используя хранимые процедуры сервера заместо SQL-запросов, генерируемых клиентским приложением. Дело в том, что переданный из клиентского приложения SQL-запрос сервером оптимизируется, компилируется и только потом производится, а хранимые процедуры сервера Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья уже содержатся в оптимизированном и скомпилированном виде, потому обработка данных с их внедрением просит наименьших издержек времени, в особенности при маленьком числе и суммарном объеме передаваемых характеристик процедуры.

Но следует подразумевать, что хранимые процедуры пишутся на процедурном расширении SQL применяемого сервера. Cуществуют официальные эталоны непроцедурного языка SQL ANSI/ISO SQL Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья-86, SQL-89 и SQL-92, но на сегодня не существует эталонов на процедурные расширения этого языка. Любая серверная СУБД имеет собственный набор процедурных расширений, отличающийся от соответственных расширений других СУБД. Некие сервера, к примеру Borland IB Database, поддерживают создание и внедрение в процедурах функций, определенных юзером (UDF - User Defined Functions), а Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья некие не поддерживают. Потому при смене платформы хранимые процедуры, вероятнее всего, будет нужно переписывать. Отметим также, что в большинстве случаев серверные хранимые процедуры создаются методом ручного кодировки, и для их сотворения, обычно, не существует комфортных зрительных средств разработки и отладки наподобие имеющихся в C++Builder. Потому при принятии решения о разработке Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья тех либо других хранимых процедур не мешает оценить вероятные трудовые затраты - время от времени возможно окажется, что они не стоят ожидаемого эффекта.

Если же хранимые процедуры используются интенсивно, еще большего увеличения производительности при их использовании можно достигнуть, минимизируя число и объем передаваемых на сервер характеристик. Разумеется, что передать на Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья сервер целое число намного проще, чем переслать длинноватую символьную строчку, потому при планировании хранимых процедур с схожими параметрами есть смысл пошевелить мозгами о перепроектировании базы данных и разработке, к примеру, таблиц-справочников или, при маленьких объемах таких таблиц, о хранении их на рабочей станции либо организации соответственных Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья массивов.

Внедрение подготовительной подготовки запросов

При использовании компонент TQuery часто бывает полезно использовать способ Prepare(), в особенности если компонент TQuery содержит параметризованный запрос. Способ Prepare() производит пересылку запроса на сервер, где он оптимизируется и компилируется, а при открытии запроса на сервер в данном случае посылаются только его характеристики. В особенности приметным Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья увеличение производительности возможно окажется тогда, когда параметризованные запросы с разными значениями характеристик повторяются нередко - в данном случае повторная подготовка запроса не будет нужно. Если же способ Prepare() не вызывается очевидно, он будет автоматом вызываться неявно всякий раз при пересылке характеристик, инициируя пересылку всего текста запроса на сервер.

Что Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья каcается передаваемых на сервер характеристик запроса, их число и объем рекомендуется минимизировать точно так же, как и в случае характеристик хранимых процедур.

Внедрение представлений (View) и параметризованных запросов.

Часто начинающие программеры употребляют динамическое создание запросов на шаге выполнения, изменяя содержимое строкового массива, содержащегося в свойстве SQL компонента TQuery Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья (к примеру, временами модифицируя предложение WHERE). При нередко циклических запросах такового типа это не самый лучший метод пересылки запросов на сервер, потому что в данном случае непременно осуществляется подготовительная подготовка запросов, заключающаяся в пересылке всего текста на сервер, также оптимизации и компиляции его сервером. Более желаемым в данном случае является Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья внедрение параметризованных запросов и способа Prepare(), или внедрение представлений (View) сервера, представляющих из себя не что другое как хранимый на сервере заблаговременно скомпилированный запрос. В последнем случае реально избежать не только лишь излишних повторных компиляций запроса сервером, да и лишней перегрузки клиента генерацией запросов.

Внедрение характеристики UpdateMode

Свойство Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья UpdateMode компонент TDBDataSet определяет состав оператора WHERE, генерируемого BDE при обновлении данных. Разглядим, каким получится оператор WHERE при редактировании поля SYMBOL содержащейся на сервере Oracle Workgroup Server копии таблицы HOLDINGS из входящей в набор поставки C++Builder базы данных BCDEMOS при различных значениях этого характеристики. Сгенерированные SQL-предложения можно Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья пронаблюдать при помощи SQL Monitor.

По дефлоту значением характеристики UpdateMode является UpWhereAll, и в данном случае BDE генерирует предложение WHERE, содержащее все поля таблицы. При всем этом сгенерированный оператор SQL, если только он не переопределен при помощи компонента TUpdateSQL, будет смотреться последующим образом:

UPDATE "HOLDINGS" SET "SYMBOL"=:1 WHERE "ACCT_NBR"=:2 AND Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья "SYMBOL"=:3 AND "SHARES"=:4 AND "PUR_PRICE"=:5 AND "PUR_DATE"=:6 AND "ROWID"=:7.

Этот метод определения изменяемых строк таблицы является самым неспешным (в особенности в случае таблиц с огромным числом полей), да и более надежным, потому что фактически гарантирует достоверную идентификацию записи в хоть какой ситуации, даже в случае Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья отсутствия главных полей (если, естественно, таблица удовлетворяет требованию реляционной модели, гласящему, что любая запись должна быть уникальна и, как следует, должна владеть уникальным набором полей).

Одним из других вероятных значений этого характеристики является UpWhereChanged, при котором в предложении WHERE содержатся только поля, модифицированные в данном запросе, и главные поля. В данном Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья случае запрос имеет последующий вид:

UPDATE "HOLDINGS" SET "SYMBOL"=:1 WHERE "ROWID"=:2 AND "SYMBOL"=:3

Таковой запрос производится резвее, но в данном случае вероятны коллизии при многопользовательской работе. К примеру, один юзер считывает запись для редактирования в клиентское приложение, другой сходу после чего ее удаляет, а 3-ий делает новейшую с теми Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья же значениями изменяемых полей и теми же значениями главных полей. Эта самая новенькая запись и будет модифицироваться заместо считанной. Но таковой случай маловероятен, в особенности если ставшие ненадобными первичные ключи удаленных записей какое-то время не употребляются (к примеру, при разработке ключей при помощи генераторов последовательностей Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья).

Третьим вероятным значением характеристики UpdateMode является UpWhereKeyOnly. В данном случае предложение WHERE содержит только ключевое поле:

UPDATE "HOLDINGS" SET "SYMBOL"=:1 WHERE "ROWID"=:2

Хотя это самый резвый метод обновления данных по сопоставлению с 2-мя прошлыми вариантами, он в общем случае опасен. В данном случае появление ситуации, когда модифицируемое поле окажется модифицированным другим Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья юзером, никак не контролируется, что может привести к непредсказуемым результатам при многопользовательском редактировании данных. Потому применение значения UpWhereKeyOnly допустимо исключительно в том случае, когда возможность одновременной модификации одной и той же записи несколькими юзерами очень мала.

Увеличение эффективности SQL-запросов

Действенное программирование на SQL - тема очень широкая, достойная Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья отдельной статьи (и даже не одной). Возможность и результативность использования многих приемов оптимизации часто находится в зависимости от особенностей применяемого сервера баз данных и управляющей его работой операционной системы. Потому тут мы только коротко перечислим более нередко употребляемые приемы оптимизации SQL-предложений.

Если требуется найти наличие в таблице записей, удовлетворяющих Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья какому-либо условию, следует предпочесть внедрение предиката EXIST запросу, вычисляющему число таких записей. Запрос вида

SELECT * FROM WHERE (SELECT COUNT (*) FROM WHERE ) >0

принудит сервер при выполнении внутреннего подзапроса перебрать все строчки таблицы, проверяя соответствие каждой записи обозначенному условию, тогда как запрос вида

SELECT * FROM WHERE EXISTS (SELECT * FROM Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья WHERE )

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

Многие приемы оптимизации связаны с внедрением индексов. Если какое-либо поле таблицы нередко употребляется в предложении WHERE, сравнивающем его значение с какой-нибудь константой либо параметром, наличие Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья индекса для этого поля ускоряет подобные операции. По этой же причине рекомендуется регистрировать наружные ключи у таблиц с огромным числом записей. Но следует подразумевать, что поддержка индексов замедляет операции вставки записей, потому при проектировании данных следует взвесить все "за" и "против" сотворения индексов, а еще лучше - провести соответственное тестирование Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья, заполнив таблицы случайными данными (для этой цели можно написать соответственное приложение, а еще лучше - пользоваться готовыми средствами тестирования типа SQA Suite).

Говоря об использовании индексов, следует также направить внимание на то, что при использовании индексированных полей в качестве аргументов функций наличие индекса не оказывает влияние на скорость выполнения запроса Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья - индекс в данном случае не употребляется.

Особо необходимо подчеркнуть трудности, связанные с внедрением вложенных запросов. Дело в том, что скорость выполнения запроса значительно находится в зависимости от числа уровней вложенности подзапросов (время выполнения приблизительно пропорционально произведению числа записей в таблицах, применяемых в подзапросах). Практически проверка соответствия условию WHERE каждой Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья записи из наружного подзапроса инициирует выполнение внутреннего подзапроса, что в особенности приметно сказывается при большенном числе записей. В практике создателя чуток более года вспять был случай, когда при приведении в порядок одной из применяемых корпоративных информационных систем после выполнения нескольких обыденных запросов на обновление данных в таблице с несколькими Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья десятками тыщ записей, выполнявшихся в течение нескольких секунд, был инициирован вложенный запрос на обновление данных к этой же таблице. Этот запрос производился более 2-ух часов (чего, вообщем говоря, и следовало ждать). Потому использовать вложенные запросы следует исключительно в тех случаях, когда без их нельзя обойтись. Кандидатурой использования Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья вложенных запросов может служить фильтрация результатов обыденного запроса в клиентском приложении или последовательное выполнение нескольких запросов с созданием временных таблиц на сервере.

Оптимизация клиентского приложения

Способы оптимизации клиентского приложения не достаточно чем отличаются от способов оптимизации обыденных приложений C++Builder. Обычно оптимизация заключается в повышении быстродействия приложения и в понижении объема Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья применяемых ресурсов операционной системы.

Понижение количества потребляемых ресурсов может быть различными методами. Основной принцип их экономии - не использовать ресурсы впустую. Вот поэтому рекомендуется в приложениях, использующих огромное количество форм, создавать их динамически и уничтожать, как они становятся ненадобными (что отличается от установок менеджера проектов по дефлоту Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья, которые подразумевают автоматическое создание всех форм сразу). Но при всем этом следует держать в голове, что модуль данных, содержащий составляющие доступа к данным, применяемые интерфейсными элементами динамически создаваемой формы, должен быть сотворен до сотворения самой формы, чтобы избежать исключительной ситуации, связанной с воззванием к несуществующему объекту.

Избегать излишних связей Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья с сервером следует не только лишь из-за излишней перегрузки сети и сервера, да и из-за того, что они поглощают некое количество ресурсов и замедляют работу приложения.

Еще одним методом экономии ресурсов клиентского приложения является внедрение более эконом интерфейсных частей в случаях, где это может быть (к примеру, TDBText Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья либо TLabel заместо TDBEdit, TLabel заместо TDBMemo при отображении полей, редактирование которых не подразумевается, TDBGrid заместо TDBControlGrid и т.д.).

Очередной прием, повышающий быстродействие клиентского приложения, заключается в сокращении числа операций, связанных с выводом данных из таблиц на экран, к примеру, при "пролистывании" огромного количества строк в компонентах типа TDBGrid либо Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья TDBCtrlGrid в процессе навигации по набору данных либо какой-нибудь их обработки. В данном случае рекомендуется на время отключать связь интерфейсных частей с компонентом TDataSource, установив значение его характеристики Enabled равным false (пример использования этого приема будет приведен ниже).

О навигационных способах и "клипперном" стиле програмирования

Говоря об оптимизации клиент Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья-серверных информационных систем, хотелось бы раздельно тормознуть на одной очень всераспространенной ошибке, совершаемой программерами, имеющими большой опыт работы с настольными СУБД и средствами разработки, базирующимися на xBase-языках, такими, как Clipper, dBase, FoxPro и др. При использовании средств разработки такового рода какое-либо изменение данных в Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья таблице согласно любым правилам осуществляется обычно методом сотворения цикла типа:

USE HOLDINGS

GO TOP

DO WHILE !EOF()

PUR_PRICE=PUR_PRICE+10

SKIP

ENDDO

CLOSE

В приведенном куске xBase-кода PUR_PRICE - имя поля таблицы HOLDINGS, подверженного изменению.

При переходе к архитектуре клиент/сервер и средствам разработки, поддерживающим SQL, сначала появляется естественное желание продолжать писать схожий Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья код, используя циклы и навигацию по таблице. Это не так жутко в случае использования C++Builder с настольными СУБД - локальный SQL, способный быть кандидатурой в данном случае, в итоге также инициирует перебор записей таблицы. Вообщем говоря, то же самое происходит и при выполнении запроса типа UPDATE HOLDINGS Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья SET PUR_PRICE=PUR_PRICE+10 на сервере баз данных, но схожий цикл является внутренним процессом сервера, в каком не задействованы ни клиент, ни сеть. Но при использовании "клипперного" стиля программирования библиотека BDE совсем не должна догадываться, что имел в виду программер, написавший схожий цикл, и генерирует совсем не такие запросы Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья!

Разглядим обычной пример. Сделаем копию таблицы HOLDINGS.DBF из входящей в набор поставки C++Builder базы данных DBDEMOS на каком-либо сервере баз данных, к примеру, Personal Oracle (воспользовавшись, к примеру, утилитой Data Migration Wizard из комплекта поставки Borland C++Builder). Потом сделаем новое приложение, состоящее из одной формы Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья, включающей составляющие TDBGrid, TTable, TDataSource, TQuery, TDBNavigator и три кнопки (рис.3).

Установим последующие значения параметров применяемых компонент (табл.1):

Таблица 1.

Компонент Свойство Значение
DBNavigator1 DataSource DataSource1
DBGrid DataSource DataSource1
Button1 Caption 'Use SQL'
Button2: Caption 'Update records'
Button3: Caption 'Exit'
DataSource1 DataSet Table1
Table1 DatabaseName ORACLE7
TableName HOLDINGS
UpdateMode UpWhereKeyOnly
Table1PUR_PRICE FieldName 'PUR_PRICE'
Query1 DatabaseName ORACLE7
SQL 'UPDATE HOLDINGS SET PUR_PRICE=PUR_PRICE+10'

Сейчас Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья сделаем обработчики событий, связанные с нажатием на кнопки. Кнопка Update records реализует аналог куска xBase-кода, приведенного выше:

void __fastcall TForm1::Button2Click(TObject *Sender)

{

Table1->First();

DataSource1->Enabled=false; //Небудемиздеватьсянадвидеоадаптером!

while (!Table1->Eof)

{

Table1->Edit();

Table1PUR_PRICE->Value=Table1PUR_PRICE->Value+10;

Table1->Next();

}

DataSource1->Enabled=true; //Поглядим, чтополучилось Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья...

}

Временное отключение связи меж DataSource1 и Table1 в данном обработчике событий изготовлено для того, чтоб исключить перерисовку компонента DBGrid1 при изменении каждой записи.

Кнопка Use SQL реализует выполнение одиночного SQL-запроса UPDATE HOLDINGS SET PUR_PRICE=PUR_PRICE+10:

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Query1->Prepare();

Query1->ExecSQL Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья();

Table1->Refresh(); //Посмотримнарезультат...

}

Скомпилировав приложение, запустим SQL Monitor и поглядим, какие запросы генерируются BDE при нажатии на эти кнопки.

При использовании кнопки Update records log-файл имеет последующий вид:

14:37:08 SQL Prepare: ORACLE - UPDATE "HOLDINGS" SET "PUR_PRICE"=:1 WHERE "ROWID"=:2

14:37:08 SQL Execute: ORACLE - UPDATE "HOLDINGS" SET "PUR_PRICE"=:1 WHERE Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья "ROWID"=:2

14:37:08 SQL Stmt: ORACLE - Close

14:37:08 SQL Prepare: ORACLE - SELECT "ACCT_NBR" ,"SYMBOL" ,"SHARES" ,"PUR_PRICE" ,"PUR_DATE" ,"ROWID" FROM "HOLDINGS" WHERE "ACCT_NBR"=:1

14:37:08 SQL Execute: ORACLE - SELECT "ACCT_NBR" ,"SYMBOL" ,"SHARES" ,"PUR_PRICE" ,"PUR_DATE" ,"ROWID" FROM "HOLDINGS" WHERE "ACCT_NBR"=:1

14:37:08 SQL Misc: ORACLE - Set rowset size

14:37:08 SQL Stmt: ORACLE - Fetch Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья

14:37:08 SQL Stmt: ORACLE - EOF

14:37:08 SQL Stmt: ORACLE - Close

14:37:08 SQL Prepare: ORACLE - UPDATE "HOLDINGS" SET "PUR_PRICE"=:1 WHERE "ROWID"=:2

И т.д., пока не кончатся все записи:

14:37:10 SQL Prepare: ORACLE - SELECT "ACCT_NBR" ,"SYMBOL" ,"SHARES" ,"PUR_PRICE" ,"PUR_DATE" ,"ROWID" FROM "HOLDINGS" WHERE "ACCT_NBR"=:1

14:37:10 SQL Execute: ORACLE Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья - SELECT "ACCT_NBR" ,"SYMBOL" ,"SHARES" ,"PUR_PRICE" ,"PUR_DATE" ,"ROWID" FROM "HOLDINGS" WHERE "ACCT_NBR"=:1

14:37:10 SQL Misc: ORACLE - Set rowset size

14:37:10 SQL Stmt: ORACLE - Fetch

14:37:10 SQL Stmt: ORACLE - EOF

14:37:10 SQL Stmt: ORACLE - Close

Отметим, что это еще не наибольший набор запросов для данного варианта, потому что при обновлении таблицы было применено Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья значение UpWhereKeyOnly характеристики UpdateMode компонента Table1, при котором запросы на обновление одной записи имеют малый набор проверяемых характеристик.

При использовании кнопки Use SQL log-файл имеет совсем другой вид:

14:35:51 SQL Prepare: ORACLE - UPDATE HOLDINGS SET PUR_PRICE=PUR_PRICE-10

14:35:51 SQL Transact: ORACLE - Set autocommit on/off

14:35:51 SQL Execute Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья: ORACLE - UPDATE HOLDINGS SET PUR_PRICE=PUR_PRICE-10 14:35:51 SQL Stmt: ORACLE - Close

Другие SQL-запросы, находящиеся в log-файле, генерируются BDE при выполнении способа Refresh() компонента Table1:

14:35:51 SQL Prepare: ORACLE - SELECT "ACCT_NBR" ,"SYMBOL" ,"SHARES" ,"PUR_PRICE" ,"PUR_DATE" ,"ROWID" FROM "HOLDINGS" WHERE "ACCT_NBR"=:1

14:35:51 SQL Execute Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья: ORACLE - SELECT "ACCT_NBR" ,"SYMBOL" ,"SHARES" ,"PUR_PRICE" ,"PUR_DATE" ,"ROWID" FROM "HOLDINGS" WHERE "ACCT_NBR"=:1

14:35:51 SQL Misc: ORACLE - Set rowset size

14:35:51 SQL Stmt: ORACLE - Fetch

14:35:51 SQL Stmt: ORACLE - EOF

14:35:51 SQL Stmt: ORACLE - Close

14:35:51 SQL Prepare: ORACLE - SELECT "ACCT_NBR" ,"SYMBOL" ,"SHARES" ,"PUR_PRICE" ,"PUR_DATE" ,"ROWID" FROM "HOLDINGS" WHERE (("ACCT Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья_NBR" IS NULL OR "ACCT_NBR"> :1)) ORDER BY "ACCT_NBR" ASC

14:35:51 SQL Execute: ORACLE - SELECT "ACCT_NBR" ,"SYMBOL" ,"SHARES" ,"PUR_PRICE" ,"PUR_DATE" ,"ROWID" FROM "HOLDINGS" WHERE (("ACCT_NBR" IS NULL OR "ACCT_NBR"> :1)) ORDER BY "ACCT_NBR" ASC

14:35:51 SQL Misc: ORACLE - Set rowset size

14:35:51 SQL Stmt Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья: ORACLE - Fetch

Если из текста обработчика действия Button1Click удалить строчку

Table1->Refresh();,

то деяния с 5-го по 14-е производиться не будут. Не считая того, при нажатии на эту же кнопку пару раз попорядку log-файл будет иметь последующий вид:

14:11:36 SQL Prepare: ORACLE - UPDATE HOLDINGS SET PUR_PRICE=PUR_PRICE Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья-10

14:11:36 SQL Execute: ORACLE - UPDATE HOLDINGS SET PUR_PRICE=PUR_PRICE-10

14:11:40 SQL Stmt: ORACLE - Reset

14:11:40 SQL Execute: ORACLE - UPDATE HOLDINGS SET PUR_PRICE=PUR_PRICE-10

14:14:17 SQL Stmt: ORACLE - Reset

14:14:17 SQL Execute: ORACLE - UPDATE HOLDINGS SET PUR_PRICE=PUR_PRICE-10

14:14:19 SQL Stmt: ORACLE - Reset

Как лицезреем, компиляция запроса сервером осуществляется Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья в данном случае только один раз.

Итак, мы лицезреем, что "клипперный" стиль программирования при работе с SQL-серверами полностью неприемлем - он приводит к перегрузкам сервера, сети и рабочей станции сразу, а разница в скорости выполнения видна даже при маленьком объеме таблицы и использовании локального сервера, потому, анализируя предпосылки низкой Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья производительности приложений, стоит поглядеть - ан нет ли в клиентском приложении схожих фрагментов кода?

В заключение хотелось бы отметить, что оптимизация клиент-серверных информационных систем должна выполняться с учетом результатов анализа производительности и кропотливого тестирования, может быть, не только лишь при помощи SQL Monitor, да и при помощи особых средств тестирования Оптимизация приложений С++Builder в архитектуре клиент/сервер - статья, владеющих дополнительными многофункциональными способностями.



optika-8-rasseyanie-sveta-vidi-opticheskih-neodnorodnostej-pokazatel-rasseyaniya-zakon-releya.html
optika-referat.html
optiko-mehanicheskie-mishi.html