Содержание


Производительность приложений для Lotus Notes/Domino 7

Часть 2: Оптимизация представлений базы данных

Серия контента:

Этот контент является частью # из серии # статей: Производительность приложений для Lotus Notes/Domino 7

Следите за выходом новых статей этой серии.

Этот контент является частью серии:Производительность приложений для Lotus Notes/Domino 7

Следите за выходом новых статей этой серии.

В статье "Производительность приложений для Lotus Notes/Domino 7: Часть 1" мы исследовали, как можно улучшить производительность приложений для Lotus Notes/Domino 7 путем эффективного использования свойств базы данных и коллекций документов. Во второй части мы рассмотрим, как можно создавать высокопроизводительные представления. Как и часть 1, эта статья предоставляет много фрагментов кода, который вы можете использовать повторно и адаптировать под ваши требования.

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

В данной статье предполагается, что вы являетесь опытным разработчиком приложений для Notes/Domino.

Освоение индексации представлений (задание Update)

Первое, что вы должны знать перед устранением проблем производительности, которые могут быть связаны с индексацией представлений, это то, как работает индексация. Индексация, обычно, выполняется заданием Update, которое выполняется каждые 15 минут на сервере Domino. Технически возможно настроить этот интервал, но для этого требуется переименование файлов, поэтому настройка делается редко.

Задание Update ищет на сервере каждую базу данных, имеющую более позднее время изменения, чем время последнего запуска задания Update. Затем задание обновляет представления в таких базах данных. Основываясь на собственном опыте, мы справедливо предполагаем, что обновление обычного представления в рабочей базе данных в рабочей среде занимает примерно 100 миллисекунд.

Логично задать вопрос: "Что сигнализирует о том, что представление нуждается в обновлении?" Представлене должно быть обновлено каждый раз при возникновении любого из следующих событий:

  • Репликация передает модификацию документа в базу данных;
  • Пользователь сохраняет или удаляет документ (и затем покидает базу данных);
  • Маршрутизатор передает документ.

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

Существует маленький трюк: пользователи могут немедленно передать запрос с высоким приоритетом на обновление представления, открывая представление или находясь в представлении, где они сделали изменение документа. Рассмотрим пример.

Предположим Элис открыла базу данных Contact Management в представлении #1 в 9:02 AM. Предположим также, что задание Update запустилось в 9:00:00 и будет запущено снова в 9:15:00, 9:30:00 и т.д. Элис обновила пару документов в 9:05 AM. Она создала новые документы, отредактировала существующие, или, возможно, удалила документы. В любом случае, сервер немедленно обновляет представление #1, потому что она находится в этом представлении. Будет странно, если вы удаляете документ и все равно видите его в представлении, не так ли? То есть, представление обновляется сразу. Но остальные представления ставятся в очередь на обновление в 9:15 AM.

Теперь представьте, что Боб тоже работает с нашей базой данных Contact Management в 9:02 AM. Он работает с представлением #1. В 9:05 AM он видит синюю стрелку перезагрузки в верхнем левом углу, указывающую на то, что представление обновилось. Он нажимает клавишу F9 или нажимает мышкой кнопку со стрелкой обновления, и представление быстро отобразит обновленное содержимое. Он не должен ждать обновления.

Далее, предположим, что Кэти тоже работает с базой данных в 9:02 AM. Она использует представление #2. Если она ничего не делает для принудительного обновления в этом промежутке времени (что возможно, но нежелательно), то увидит синюю стрелку перезагрузки в 9:15 AM, когда ее представление обновится заданием Update. Хотя более вероятно, что Кэти сделает свои собственные обновления данных, прокрутит представление достаточно для принудительного обновления, или перейдет в другое представление. Любое из этих действий вызовет немедленное обновление.

В 9:15 AM все представления, которые эти пользователи еще не обновили принудительно, обновляются, и мы начинаем все заново.

Дополнительная информация по индексации представлений

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

Во-вторых, разработчик может установить параметры индексации в свойствах представления. Многие ошибочно думают, что это параметры влияют на то, как будут работать задания Update или Updall. Это не так. Задания Update и Updall будут полностью игнорировать эти параметры, обновляя представления только на основе критериев, описанных в предыдущем примере.

Параметры индексации влияют на то, что происходит, когда пользователь открывает представление. Например, если параметры установлены в "manual" ("вручную"), пользователь получает представление (возможно, устаревшее) очень быстро. Если параметры установлены в "Auto, at most every n hours" ("Автоматически, не реже n часов"), и если прошло времени больше указанного интервала, пользователь должен будет немного подождать, пока представление не обновится, также как если бы оно было обычным представлением с параметром индексации "Automatic" ("Автоматически"). Позднее в данной статье мы рассмотрим, как эти параметры индексации можно использовать для создания полезных представлений.

Краткие советы по поиску неполадок индексации представлений

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

  • Длинные задержки при открытии базы данных, открытии представления, переключении представлений, прокрутке содержимого представления или сохранении документа;
  • Задержки при открытии документа, использующего операции поиска (lookup). Фактически, вы можете увидеть форму, застывшую на определенной точке и ожидающую завершения этих операций поиска;
  • Проблемы производительности во время рабочего дня, но отличная производительность во внерабочее время;
  • Устаревшие полнотекстовые индексы.

Следующие параметры Notes.ini для ведения журналов и отладки могут помочь вам решить эти проблемы:

ПараметрОписание
log_update=1Записывается дополнительная информация в представление log.nsf Miscellaneous Events. Она состоит из строки информации, записываемой каждый раз при запуске заданием Update обновления базы данных, и второй строки, записываемой при окончании обновления. Каждая строка имеет метки даты/времени, найдя разность которых, вы можете получить примерное время (округленное до ближайшей секунды), необходимое для обновления этой базы данных.
log_update=2Записывается дополнительная информация в журнал. В дополнение к данным, генерируемым при log_update=1, данный параметр добавляет одну строку информации для каждого представления в каждой базе данных. То есть, база данных с 75 представлениями имела бы 77 строк - одну строку, указывающую начало обновления заданием Update этой базы данных, 75 строк по одной для каждого представления, и завершающую строку, указывающую конец индексации этой базы данных.
debug_nif=1Собирая намного больше подробной информации по индексации, debug_nif будет писать ее в текстовый файл (который вы указываете при помощи строки debug_outfile=c:\temp, например). При этом легко могут сгенерироваться гигабайты данных в час, поэтому этот параметр надо использовать расчетливо, если вообще использовать. Значение этой отладочной переменной состоит в том, что она выдает вам схему всех действий по индексации в миллисекундах, а не только информацию о задании Update, работающем каждые 15 минут.
client_clock=1Используется на вашей клиентской машине, не на сервере. При указании этого параметра будет записываться подробная информация в текстовый файл (который вы указываете при помощи строки debug_outfile=c:\temp, например) о каждом выполняемом клиентском действии. Например, она может быть использована для определения того, вызвана ли задержка, которую видит клиент, длительным временем ожидания при индексации.

Для исправления проблем индексации представлений начните со сбора некоторых данных из log.nsf, установив log_update=1 (если он еще не установлен), и позвольте серверу собирать информацию по обновлениям представлений в течение суток. Затем просмотрите представление log.nsf Miscellaneous Events за эти сутки и найдите повторяемые структуры. Некоторыми из значимых структур, которые могут появляться, являются:

  • Очень продолжительные времена для конкретной базы данных. Это может указывать на то, что база данных имеет слишком много обновляемых данных, слишком много сложных представлений, или представлений, чувствительных к времени/дате (если версия сервера равна 5 или меньше). Следующим логичным шагом является исследование использования и дизайна этой базы данных, а также, возможно, использование log_update=2 в течение суток для точного определения проблемных представлений в этой базе данных.
  • Очень продолжительные циклы обновления. Мы встречали циклы, продолжавшиеся от четырех до пяти часов. Это означает, что вместо прохождения по всем измененным базам данных каждые 15 минут задание Update может выполнить свою работу только два или три раза в день. Это может указывать на общие проблемы производительности, влияющие на все задания, или указывающие, возможно, на очень большую нагрузку (пользователей или данных) на сервер. Следующим логичным шагом могла бы быть оценка общего состояния сервера и его использования.

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

Тестирование производительности представления

Для тестирования производительности различных функциональных возможностей и способов создания представлений мы создали базу данных с 400000 документов и запустили запланированного агента для обновления 4000 документов каждые пять минут. Затем мы создали примерно 20 представлений; каждое имело несколько иные возможности, но при этом отображало все 400000 документов, используя пять столбцов. Мы приведем подробности позднее, но в общем плане картина выглядит так:

  • Время, необходимое для перекомпоновки или обновления вашего представления будет прямо пропорционально размеру представления. Если размер вашего представления увеличился в два раза - то же самое произойдет со временем, необходимым для перекомпоновки или обновления этого представления. То есть, например, если у вас есть база данных в 100MB и вы ожидаете, что она будет увеличиваться в размерах в два раза каждые шесть месяцев, и в настоящее время ее индексация происходит примерно за 30 секунд, значит вы должны ожидать, что эта индексация будет происходить за 60 секунд через шесть месяцев, за 120 секунд через следующие шесть месяцев и т.д.
  • Самыми большими "убийцами производительности" в терминах индексации представлений являются категоризированные столбцы. Столбцы сортировки добавляют небольшие накладные расходы, так же как и некоторые другие функциональные возможности, например, параметр "Generate unique keys" ("Генерировать уникальные ключи"). Мы расскажем об этом подробнее в советах в конце статьи.

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

Рисунок 1. Размер индекса представления и время реакции
Размер индекса представления и время реакции
Размер индекса представления и время реакции

А на рисунке 2 показана зависимость времени реакции от размера представления.

Рисунок 2. Размер представления и время реакции
Размер представления и время реакции
Размер представления и время реакции

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

Поле Reader Names

За последние несколько лет мы увидели серьезное увеличение количества критических ситуаций, относящихся к полям Reader Names и представлениям. Пользователи обнаружили, что в течение дня производительность часто неприемлема. Они не могут понять почему, поскольку просмотры кода и все контрольные испытания проходят нормально. Но через несколько месяцев после развертывания системы в их подразделении/отделе/компании они обнаруживают, что жалобы на производительность доминируют при общении с работниками и что нужно что-то делать.

Примеры

Нашими любимыми примерами являются приложения HR (Кадры) и Sales Force (Продавцы), обычно имеющие элементы управления полями Reader Names. В следующей таблице показан гипотетический сценарий для компании, использующей базу данных из 400000 документов.

Должность/рольКоличество документов, которые может увидеть пользователь (из 400000) Процент базы данных
Corporate HQ (генеральный директор), CEO (директор), CIO (директор по информационным технологиям), Domino-администраторы, разработчики400000100
Региональный менеджер40001
Менеджер4000.1
Служащий400.01

Высшее управление, Domino-администраторы и разработчики обычно имеют довольно хорошую производительность, что приводит к игнорированию первых сообщений о плохой производительности. Проблемы производительности обычно осложняются слабой связностью (WAN против LAN), что тоже может привести к кажущейся неверности ранних жалоб. Но по достижении определенного критического количества жалобы регистрируются, кто-то садится за рабочую станцию вместе с сотрудником и видит, насколько долго открывается база данных или сохраняется документ. Вот теперь звучит сигнал тревоги. На рисунке 3 показано время открытия представления в примере базы данных с 400000 документов. Все представления уже были обновлены. На тестовом сервере нет никакой другой активности, и только один пользователь обращается к серверу.

Рисунок 3. Время, необходимое для открытия представления в примере базы данных
Время, необходимое для открытия представления в примере базы данных
Время, необходимое для открытия представления в примере базы данных

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

Прежде чем перейти к объяснению полей Reader Names и производительности, мы хотим донести до вас важную мысль рисунка 3. Вы можете быстро заметить, почему пользователи "плоских" (отсортированных, не категоризированных) представлений ощущают настолько радикально различные влияния производительности этого приложения, если они составляют 0.01% от пользователей по сравнению со 100% пользователей.

Понимание полей Reader Names

Когда приложение использует поля Reader Names (Имена читателей), это означает, что некоторые или все документы имеют поля Reader Names, то есть, поля, являющиеся полями Summary Read Access. Summary означает, что данные могут отображаться в представлениях. Технически, вы можете создать поля Reader Names и предохранить их от установки флага summary, но после этого Lotus Domino не сможет правильно гарантировать защиту документов на уровне представления. Read Access означает, кто может просматривать данный документ. Поля такого типа обычно заполняют конкретными именами, названиями группы и [ролями]. Мы рекомендуем везде, где это возможно использовать [роли], а не группы, из-за более простого обслуживания и управления. По производительности они эквивалентны.

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

  • Lotus Domino проверяет документ #1, определяет, что пользователь может его просматривать, и отображает его.
  • Lotus Domino проверяет документ #2, определяет, что пользователь может его просматривать, и отображает его.
  • Lotus Domino проверяет документ #3, определяет, что пользователь не может его просматривать, и скрывает документ от пользователя.

Процесс продолжается до тех пор, пока сервер Lotus Domino не проверит все документы в представлении. Естественно, представление нужно сначала обновить, иначе сервер не будет знать, какой документ был #1, или каковы были его значения Reader Names. Давайте сделаем паузу в этом объяснении и рассмотрим классический пример плохой производительности. Представим на минуту, что наша база данных является приложением Sales Tracking (Отслеживание продаж), и имеет представление By Revenue (По доходам), которое отсортировано по убыванию суммы контракта. Предположим, что представление содержит пять столбцов с отсортированными первыми двумя столбцами (например, Revenue и SalesRep). Категорий нет. В этом случае, открывая представление (которое потенциально отображает 400000 документов), пользователь вынужден сначала его обновить, при необходимости, а затем сервер начинает с документа #1 и проверяет, можно ли его отображать пользователю, потом проверяет документ #2, #3 и т.д.

По-видимому, вы читаете эту статью через Web-браузер, и, возможно, знакомы с тем фактом, что браузеры формируют некоторые части страницы быстро (текст), а некоторые части (например графику) более медленно. Но сервер Domino работает с представлениями иначе. Он не посылает какую-либо часть документа пользователю, пока не будет иметь, по его мнению, полный экран информации. На практике это может быть, например, 60 строк данных. Вы можете проверить данный факт сами, открыв в Notes-клиенте "плоское" представление (нет категоризированных столбцов) и нажав клавишу "стрелка вниз". Сначала представление прокручивается быстро. Затем появляется пауза. В это время сервер готовит для вас несколько следующих килобайт данных. Затем представление опять прокручивается быстро по другим 60 (или около того) строкам. Это повторяется до тех пор, пока вы удерживаете клавишу "стрелка вниз".

Вернемся к нашему пользователю. Обнаруживается, что он может просматривать документ #1, но, возможно, не может видеть следующие 10000 документов. Почему? Может быть, ему разрешено просматривать только 40 документов из всей базы данных. Поскольку сервер Domino не собирается ему отображать что-либо до тех пор, пока не сформирует 60 строк информации (либо пока не дойдет до конца представления), появится длинная задержка.

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

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

Одним из таких обходных путей является категоризация представления. Причина улучшения производительности заключается в том, что категории всегда будут отображаться и займут строку данных. То есть, в нашем примере представления By Revenue пользователь быстро увидел бы десятки категорий, отображающих, скажем, Revenue и SalesRep. Раскрытие какой-либо категории приведет к быстрой реакции сервера, определившему, что документ в этой категории не может просматриваться данным пользователем, что лучше, чем необходимость просматривать 400000 документов за один проход.

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

У нас есть две близкие идеи, касающиеся полей Reader Names и представлений. Во-первых, в нормальной рабочей среде редко получаются такие четкие данные, которые изображены на рисунке 3. Более вероятно, что вы столкнетесь с тем, что проблемы производительности, связанные с полями Reader Names, являются причиной других задержек производительности, например, в агентах, при индексации представлений и т.п. Эти проблемы могут породить другие проблемы. Например, вы можете заметить, что представления медленно отображаются у всех, и сделать заключение, что проблема в индексации представления, тогда как на самом деле она состоит в том, что поля Reader Names вызывают длительные вычисления на сервере при открытии представлений некоторыми пользователями.

Во-вторых, наши тесты (и рисунок 3) представляют собой наилучший сценарий. У нас есть только один пользователь. Мы могли бы продублировать объем данных и даже проблемы индексации при помощи наших запланированных агентов, но наши тесты не смогли бы показать нарастание проблем производительности, возникающее тогда, когда сотни пользователей одновременно пытаются обратиться к представлениям с документами, имеющими управляемый доступ по чтению. Если ваше приложение использует поля Reader Names, вы обязательно должны уделять внимание производительности представлений, если хотите избежать кризиса.

Советы по увеличению производительности представлений с документами, имеющими управляемый доступ по чтению

Ниже приведены некоторые советы по созданию приложений/представлений, хорошо работающих даже с документами, имеющими управляемый доступ по чтению:

  • Встроенное (embedded) представление, использующее Show Single Category. Это лучшее решение. Если ваши данные структурированы так, что пользователи могут видеть все документы в категории, вы очень быстро отображаете пользователю содержимое только этой категории. В некоторых случаях может иметь смысл разрешить пользователю переключать категории, и тогда вы должны учитывать, может ли он видеть содержимое других категорий. Но в большинстве случаев представление могло бы выглядеть примерно как My Sales и отображало бы все документы о продажах для данного пользователя. Возражением против такого типа представлений может быть то, что пользовательский интерфейс для Notes-клиента не такой красивый, как родное отображение представления. Но для Web-браузеров это нормально, поэтому мы не видим причин не использовать данный тип представлений для приложений, основанных на Web-браузере. Фактически, производительность настолько высока, что быстрее откроется один из таких документов с контролируемым доступом по чтению, чем родное представление без таких документов!
  • Local Replicas (локальные копии). Для базы данных, отслеживающей продажи, многие компании используют локальные копии, чтобы гарантировать возможность работы своих отделов продаж с базой данных в автономном режиме. Это, во многом, отличное решение, но работать с документами с контролируемым доступом по чтению становится труднее при изменениях значения их полей Reader Names, так как необходимо, что бы они исчезли из некоторых локальных копий и появились в других.
  • Shared, Private на часто используемых представлениях. Это элегантное решение для Notes-клиентов, но у него есть и недостатки. Во-первых, его нельзя использовать для браузеров. Во-вторых, представления должны либо сохраняться локально, что может быть проблематично для некоторых пользователей, либо на сервере, что может вызывать появление проблем производительности и обслуживания. В-третьих, при изменении дизайна приложения может быть не легко обновить дизайн этих (теперь) приватных представлений. И, в-четвертых, некоторые пользователи сталкиваются с проблемами производительности, связанными с необходимостью создания и использования большого количества таких приватных представлений.
  • Категоризированные (Categorized) представления. Как видно из рисунка 3, категоризированые представления могут открываться очень быстро (касательно полей Reader Names). Они больше и медленнее индексов, но, обычно, устраняют проблему производительности Reader Names. Возражение состоит в том, что пользователи могут посчитать такие представления выглядящими не дружественно - ярлык, который никто не хотел бы иметь на своем приложении.

Последний совет касается того, чего следует избегать. Функция "Don’t show empty categories" ("Не показывать пустые категории") могла бы, теоретически, быть очень полезной для предыдущего совета по созданию категоризированного представления, которое отображало бы только категории, содержащие видимые для пользователя документы. Однако, на практике, она приводит к характеристикам производительности представления, аналогичным плоским представлениям. Поэтому, возможно, нужно избегать использования этой функции, если важна производительность.

Общие советы по производительности представлений

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

Формулы даты/времени

Использование @Now или @Today в столбце или формуле выбора вызывает перекомпоновку представления каждый раз при его обновлении. Следовательно, если вы используете такого рода формулы, подумайте над тем, чтобы сделать представление обновляемым вручную (Manually) или автоматически через каждые n часов ("Auto, at most every n hours"). Таким образом, открывая представление, пользователи не будут ожидать перекомпоновки представления (или нечасто, в крайнем случае). Обратной стороной является то, что представление может быть устаревшим, поскольку открывается без попытки обновления. Рассмотрите содержимое таких представлений и частоту их изменения для определения того, безопасно ли использовать эти параметры индексации.

Используйте сортировку по нажатию (click-sort) разумно

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

Генерирование уникальных ключей в индексе

Одной из менее известных функциональных возможностей, улучшающих производительность, является параметр "Generate unique keys in index" ("Генерировать уникальные ключи в индексе") для поисковых представлений, который может значительно уменьшить время операций поиска. При его выборе представление устраняет все дублирующиеся записи. Например, если у вас есть 400000 документов, отображающих только CompanyName, а также только 1000 уникальных названий компаний, то выбор этой функциональной возможности приведет к тому, что для каждой компании в индексе представления будет храниться только первый документ. Хотя есть небольшие накладные расходы для этой функции, но они легко перевешиваются тем, что ваше представление может значительно уменьшиться в размерах. Одно предупреждение: если вы отображаете результаты многозначных полей, нужно использовать хитрый код, чтобы избежать потерь данных.

Например, представьте базу данных, имеющую 100000 документов, содержащих многозначное поле Industry. Вы хотите определить уникальный список уже выбранных отраслей промышленности так, чтобы ваше поле с ниспадающим списком Industry могло отображать значения при создании пользователем новых документов. Если вы используете эту функцию уникальных ключей в представлении, имеющем один столбец Industry, есть вероятность, что новый документ, содержащий значения Automotive и Air, не будет отображаться, поскольку другой документ, содержащий Automotive, уже отображается в представлении. Следовательно, ваше новое значение Air никогда не будет выбрано формулой поиска.

Для устранения этой проблемы используйте формулу @Implode(Industry; "~") в качестве формулы столбца, и тогда поисковая формула ниспадающего списка может выглядеть так: @Explode(@DbColumn("Notes"; ""; "(LookupViewName)"; 1); "~"). Хотя будет иметь место небольшое дублирование данных в вашем представлении, вы будете защищены от потерь данных.

Цветовые профили

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

Представление по умолчанию

Когда бы ни открывалось ваше приложение, открывается представление по умолчанию. Всегда добивайтесь, чтобы это представление открывалось быстро. Интересным примером является почтовый файл. Для многих пользователей представление, которое открывается по умолчанию, является Inbox (папка). Если пользователь не имеет привычки очищать свою папку Inbox, и в ней находятся многие тысячи документов, его почтовый файл откроется медленнее, чем при регулярной очистке папки Inbox и при наличии в представлении/папке десятков или сотен документов. Кстати, вот почему некоторые компании придерживаются политики периодического удаления старых документов из папки Inbox. Они заставляют пользователей перемещать эти документы в другие папки, повышая, тем самым, производительность как для пользователя, так и для сервера.

Заключение

Мы надеемся, что из данной серии статей вы поняли, что производительность приложения может зависеть от вас. Внимательно продумывая работу приложений (и, возможно, используя некоторую информацию и советы из данной статьи), вы можете сохранить их производительность на более чем приемлемом для ваших пользователей уровне.


Ресурсы для скачивания


Похожие темы

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Lotus
ArticleID=158478
ArticleTitle=Производительность приложений для Lotus Notes/Domino 7: Часть 2: Оптимизация представлений базы данных
publish-date=02142006