При описании в метаданных реквизитов различных объектов существует возможность установить свойство Индексировать . Это свойство позволяет разработчику конфигурации указать системе необходимость построения в базе данных отдельного индекса по соответствующему реквизиту.
Кроме варианта «Индексировать» в данном свойстве для большинства объектов можно установить вариант «Индексировать с доп. упорядочиванием». Данный вариант предназначен, прежде всего, для использования в динамических списках.
В варианте «Индексировать» строится индекс непосредственно по реквизиту. Индекс также дополняется ссылкой, чтобы обеспечить определенный порядок записей в индексе при повторяющихся значениях реквизита.
В варианте «Индексировать с доп. упорядочиванием» индекс строится по реквизиту, а также по некоторому полю, которое обычно используется для упорядочивания объектов этого типа. Для справочника индекс в зависимости от основного представления дополняется кодом или наименованием. А для документа, индекс дополняется датой. Этот индекс также дополняется ссылкой.
В варианте «Индексировать» в динамическом списке может быть обеспечен эффективный просмотр больших объемов информации с упорядочиванием по данному реквизиту, так как для этого будет использоваться созданный индекс.
В варианте «Индексировать с доп. упорядочиванием» в динамическом списке может быть обеспечен эффективный просмотр больших объемов информации с отбором по значению данного реквизита и с упорядочиванием, соответствующим основному упорядочиванию для данного объекта. В этом случае наличие индекса включающего реквизит, по которому выполняется отбор, и поля основного упорядочивания позволит системе использовать индекс при просмотре списка.
Разумеется, индексы так же влияют и на другие способы выборки информации (получение данных с помощью методов менеджеров объектов или запросов).
Таким образом при определении варианта свойства Индексировать следует исходить из того, какие варианты выборки информации необходимо оптимизировать в первую очередь. Например, если требуется просмотр списка с отбором по реквизиту, то имеем смысл использовать вариант «Индексировать с доп. упорядочиванием». А если индекс нужен, например, только для поиска с помощью запроса объектов по данному реквизиту без упорядочивания, то лучше использовать вариант «Индексировать», чтобы создаваемые индекс требовал меньше ресурсов системы.
Подробно состав индексов формируемых системой при различных сочетаниях свойств метаданных приводится в с статье «Индексы таблиц базы данных».
Сегодня пришлось оптимизировать свой запрос, который выполнялся 34 секунды.
Приведу его изначальные характеристики:
- 3 среза последних
- 1 вложенный запрос
- 3 левых соединения
- РАЗЛИЧНЫЕ в первой выборке
- 7 условий по параметрам+1 по определенному в запросе значению
- Начальная выборка 215000->19000 результирующих, которые затем средствами СКД группировались в более скромную выборку
Итерации поиска причин
Подозрение вызвали соединения, убрал — нулевой результат.
Ушел от вложенного запроса — нулевой результат.
Ушел от полей в выборке через точку — 0.
Ушел от РАЗЛИЧНЫЕ — 0.
Условия в запросе по реквизитам Регистра сведений, проверил — Индексируются на уровне базы данных.
В итоге, от изначального запроса остался запрос срез последних с условиями ГДЕ (через параметры виртуальной таблицы условия не при применимы по логике требуемого результата).
Думаю «эврика», медленно срез последних выполняется, но ничего не поделаешь же, формирую без условий — моментально.
Перебираю комбинации из 3 условий — только замедление.
Вспоминаю про ИНДЕКСИРОВАТЬ ПО, которые обычно использовал при соединениях, но и в этих случаях не всегда давало заметный результат, возможно из-за характеристик платформы/кэширования MSSQL — сервера.
Получение данных срезом вообще без условий (215000)->Помещение во временную таблицу с индексацией 3 полей-Выборка из временной с наложением условий.
Ускорение в 15 раз (с 34 секунд до 2,27) на работающей системе
141 пользователей, даже когда вернул все соединения и условия.
А вообще, изначально думал проблема в том, что в СКД закидывается большой объем данных из таблицы значений, а пришлось препарировать запрос.
На всякий случай приведу параметры системы: Платформа 8.3.5.1068, Intel XEON E3-1220 v2, 32 GB ОЗУ, windows/MSSQL/2012 64bit, 1С 32 bit, всё на одном сервере.
Не понятно только почему не работает индексирование реквизитов на уровне базы данных или все-таки работает, а при отсутствии было бы гораздо медленней.
UPD 20/12/2015:
На неделе столкнулся с ситуацией, когда обрабатывался регистр сведения по истории реквизитов документов, обрабатывалось единовременно более 93000 документов, с 30-50 хранимых реквизитов, добавление индексации давало замедление в 2 раза.
Вывод: надо подходить к различным задачам индивидуально, в данном случае затраты на индексирование были неоправданы
Клиент получает ту рекламу, которую он заслуживает!
Разработчики 1С очень часто игнорируют использование конструкции «ИНДЕКСИРОВАТЬ ПО» в запросе.
Зачем нужно индексировать поля в запросе 1С 8.3, я расскажу ниже.
Как работает ИНДЕКСИРОВАТЬ ПО?
Индексация в запросе нужна для более быстрого формирования результате запроса. Как это работает? Система строит индекс для временной таблицы, чтобы быстрее найти нужное значение.
Т.е. система работает точно так же, как и обычные индексы 1С, только для временной таблицы.
Где и как нужно использовать ИНДЕКСИРОВАТЬ ПО ?
Конструкцию рекомендуется использовать по полям временных таблиц, по которым эта временная таблица будет соединяться с другими таблицами баз данных. Это существенно повышает скорость выполнения соединения таблиц.
Однако следует учесть один момент. Построение индекса временной таблицы также требует времени на выполнение. Поэтому целесообразно использовать конструкцию «ИНДЕКСИРОВАТЬ ПО», только если Вы знаете, что во временной таблице будет не 1-2 записи. В противном случае эффект может быть обратным — быстродействие от индексированных полей не компенсирует времени построения индекса.
- 5
- 4
- 3
- 2
- 1
(0 голосов, в среднем: 0 из 5)
Поддержите нас, расскажите друзьям!
СПРОСИТЕ в комментариях!
1. Что значит «рекомендуется использовать по полям временных таблиц, по которым эта временная таблица будет соединяться с другими таблицами баз данных»? У меня есть левое соединение где в правой части — таблица базы данных. Зачем индексировать временную таблицу если при выборке будет проводиться поиск в правой таблице? То есть индекс временной таблицы в данном случае не функционален.
2. Если я связываю 2 временные таблицы левым соединением, какую таблицу я должен индексировать?
3. В приведённом примере — какой смысл индексировать таблицу по единственному полю, если в индексе получается такое же количество записей как в таблице и (следовательно) обход индекса при выборке занимает примерно столько же времени?
Такое впечатление, что писали статью «чтоб было», не думая.
1. Вы просто индексы готовить не умеете, потому как у Вас поверхностные знания общих принципов применения и работы индексов на платформах БД. Вообще есть определенные стандарты, согласно которым проектировщики платформ БД (вменяемые) следуют, иначе спроса на их платформу не будет.
Так вот ответ на ваш вопрос — раз у вас в левом соединении временная таблица и по ней в самом запросе не идут поиск — значит у вас данные из левой таблицы выводятся в результат запроса (иначе зачем тогда Вам вообще левое соединение). А соответственно соединение по имеющимся записям в левой таблице может идти по ее (левой таблицы) индексу или по поиску (перебору) всех записей этой левой таблицы. И так по каждой строке правой. Да, если записей мало — то результат не так заметен, а то и даже… но когда записей много… Поймите — соединение, какое оно бы ни было — это соединение. И в данном случае можно всю таблицу перебирать, а можно по индексу сработать.
2. Если нужно получить максимально быстро результат выборки, особенно если многократно с этими временными таблицами — то обе. При соединении (не важно каком именно) платформа БД при наличии индекса на поле таблице — работает всегда по индексу. Это всегда быстрее.
3. Автор как раз понимает тему, это Вы не в теме и совершенно не представляете как работают индексы. Да, записей в индексе столько же будет, но принцип работы по индексу совершенно другой. Возможно, если у вас обе таблицы абсолютно аналогично отсортированы по полям соединения — то может и не такой эффект будет — но ведь это как правило не так…
В общем вывод — статью писали думая — это Вы ответили, не подумав…