Книга: Настольная книга 1С:Эксперта по технологическим вопросам
Назад: Пояснение к правилу 3 («ДЛЯ ИЗМЕНЕНИЯ»)
Дальше: Пояснение к правилу 8 (не использовать подзапросы в условиях)

Пояснение к правилу 4 (соответствие индексов и условий запроса)

Условия в запросе и индексы в базе должны соответствовать друг другу (при возникновении проблем на данном участке кода).

В качестве иллюстрации приводится фрагмент статьи К. Рупасова «Типичные причины неоптимальной работы запросов и методы оптимизации». Фрагмент приведен без изменений, за исключением ссылок на другие материалы.

Рекомендации

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

Условия используются в следующих секциях запроса:

ВЫБРАТЬ … ИЗ … ГДЕ условие>

СОЕДИНЕНИЕ … ПО условие>

ВЫБРАТЬ … ИЗ ВиртуальнаяТаблица>(, условие>)

ИМЕЮЩИЕ условие>

Для каждого условия должен существовать подходящий индекс. Подходящим является индекс, удовлетворяющий следующим требованиям:

  1. Индекс содержит все поля, перечисленные в условии.
  2. Эти поля находятся в самом начале индекса.
  3. Эти поля идут подряд, то есть между ними не «вклиниваются» поля, не участвующие в условии запроса.

При создании объекта метаданных «1С:Предприятие» автоматически создает индексы, которые должны подходить для работы большинства запросов.

Основные индексы, создаваемые «1С:Предприятием»:

В тех случаях, когда автоматически созданных индексов недостаточно, можно дополнительно проиндексировать реквизиты объекта метаданных.

Следует иметь в виду, что создание индекса ускоряет процесс поиска информации, но может несколько замедлить процесс ее изменения (добавления, редактирования и удаления). Поэтому индексы следует создавать осознанно и только в том случае, если точно известен запрос, для которого такой индекс необходим. Не следует создавать индексы «на всякий случай» или заведомо избыточные индексы. Например, никогда не следует дополнительно индексировать первое измерение регистра, поскольку для поиска по значению первого измерения подходит основной индекс таблицы итогов, который автоматически создаст платформа.

Пояснения

Если в структуре базы данных отсутствует индекс, удовлетворяющий всем перечисленным условиям, то для получения результата СУБД будет вынуждена сканировать таблицу или один из ее индексов. Это приведет к увеличению времени выполнения запроса, а также к возможному снижению параллельности системы, поскольку возрастет количество установленных блокировок.

Требования к индексу, перечисленные в рекомендациях, связаны с физической структурой индекса в СУБД. Эта структура представляет собой дерево значений проиндексированных полей. На первом уровне дерева находятся значения первого поля индекса, на втором – второго и так далее. Такая структура позволяет достичь высокой эффективности при поиске по индексу. Кроме того, она гарантирует отсутствие деградации производительности индекса с ростом количества данных.

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

Примеры

В конфигурации описан регистр накопления ТоварыНаСкладах (см. рис. 4.20.1):

Рис. 4.20.1. Структура регистра накопления «ТоварыНаСкладах» для нашего примера

Платформа «1С:Предприятие» автоматически создаст для таблицы остатков данного регистра индекс по периоду и всем измерениям в том порядке, в котором они перечислены в конфигураторе.

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

Запрос 1

Запрос.Текст = "ВЫБРАТЬ

| ТоварыНаСкладахОстатки.Склад,

| ТоварыНаСкладахОстатки.Номенклатура,

| ТоварыНаСкладахОстатки.Качество

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура = &Номенклатура) КАК

ТоварыНаСкладахОстатки";

В данном случае нарушено требование 2. В условии отсутствует отбор по первому полю индекса («Склад»). Такой запрос не сможет выполниться оптимально. Для его выполнения серверу СУБД придется перебирать (сканировать) все записи таблицы. Время выполнения этой операции напрямую зависит от количества записей в таблице остатков регистра и может быть очень большим (и будет увеличиваться с ростом количества данных).

Варианты оптимизации:

Запрос 2

Запрос.Текст = "ВЫБРАТЬ

| ТоварыНаСкладахОстатки.Склад,

| ТоварыНаСкладахОстатки.Номенклатура,

| ТоварыНаСкладахОстатки.Качество

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(

| ,

| Качество = &Качество

| И Склад = &Склад) КАК ТоварыНаСкладахОстатки";

В данном случае нарушено требование 3. Между измерениями «Склад» и «Качество» в структуре регистра находится измерение «Номенклатура», которое не задано в условии запроса. Этот запрос также не сможет выполняться оптимально. При его выполнении СУБД выполнит поиск по первому полю индекса, но затем вынужденно просканирует некоторую его часть. Сканирование приведет к увеличению времени выполнения запроса и к блокировке избыточных записей в таблице, то есть к снижению общей пропускной способности системы.

Варианты оптимизации:

Запрос 3

Запрос.Текст = "ВЫБРАТЬ

| ТоварыНаСкладахОстатки.Склад,

| ТоварыНаСкладахОстатки.Номенклатура,

| ТоварыНаСкладахОстатки.Качество,

| ТоварыНаСкладахОстатки.КоличествоОстаток

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(

| ,

| Номенклатура = &Номенклатура

| И Склад = &Склад) КАК ТоварыНаСкладахОстатки";

В этом случае требования соответствия индекса и запроса не нарушены. Данный запрос будет выполнен СУБД оптимальным способом. Обратите внимание на то, что порядок следования условий в запросе не обязательно должен совпадать с порядком следования полей в индексе. Это не является проблемой и будет нормально обработано СУБД.

Назад: Пояснение к правилу 3 («ДЛЯ ИЗМЕНЕНИЯ»)
Дальше: Пояснение к правилу 8 (не использовать подзапросы в условиях)