Индексы MS SQL и 1С 8.3
Сегодня речь пойдет о индексах СУБД MS SQL и их внутреннем устройстве. Я постараюсь рассказать о индексах и с точки зрения СУБД, и с точки зрения 1С 8.3.
Индексы — набор ссылок, упорядоченных по определенным столбцам, создаваемый с целью оптимизации производительности СУБД MS SQL.
Индексы в 1С
В системе 1С индексы создаются двумя способами — явным и неявным образом.
Создание индексов неявным образом:
Платформа создает индексы сама по заранее известным для каждого объекта метаданных ключам данных (ссылка, код, наименование, измерения и т.п.)
Создание индексов явным образом возможна тремя способами:
- Установка флага «Индексировать» у поля (реквизита/измерения). Вариант «Индексировать с доп. упорядочиванием» добавляет в индекс поле «Код» или «Наименование» (прежде всего для динамических списков).
- Добавление поля в «Критерии отбора«.
- Указание индексируемого поля в запрос с помощью конструкции «ИНДЕКСИРОВАТЬ ПО«.
Если вы только начинаете программировать в 1С или просто хотите систематизировать свои знания - попробуйте Школу программирования 1С нашего друга Владимира Милькина. Пошаговые и понятные уроки даже для новичка с поддержкой учителя.
Попробуйте бесплатно по ссылке >>
Индексы в СУБД Microsoft SQL
Индексы в СУБД MS SQL представляют из себя страницы с данными по 8 Кбайт каждая. Несмотря на то, что индексы призваны улучшить производительность СУБД, у них есть определенные недостатки — они занимают место на диске и замедляют работу СУБД на запись строк.
Виды индексов в СУБД MS SQL:
- Некластерные индексы — такие индексы не перестраивают таблицы, а лишь организуют ссылки.
- Кластерные индексы нужны для построения таблицы в соответствии с индексом. Данные упорядочены, например, по алфавиту. Недопустим для часто изменяющихся столбцов, т.к. СУБД постоянно физически перестраивает таблицу по этому индексу.
- Уникальные индексы — своего рода «надстройка» для кластерных и некластерных индексов. Такой индекс уникален по ключевым полям.
Виды ключей в СУБД:
- Первичный ключ (primary) — набор столбцов, уникально характеризующих строку.
- Внешний ключ (foreign) — поле таблицы, хранящее значение первичного ключа с целью организации связи между таблицами. 1С не использует данный вид ключей.
Важные нюансы использования индексов
Длина ключа индекса в основных СУБД (всех, кроме файлового варианта) — не более 900 байт и 16 различных полей.
Запускайте чаще дефрагментацию индексов на уровне СУБД MS SQL: при частом использовании индексов возможно появление эффекта фрагментации, нельзя допускать уровня фрагментации выше 25%.
Отсутствие индексов может привести к полному сканированию таблицы (table scan), что, в свою очередь, приведет к избыточной блокировке.
Однако не стоит включать индексацию по небольшим наборам данных (например, справочник Организации) — построение индекса может привести к обратному эффекту, быстродействие снизится.
К сожалению, мы физически не можем проконсультировать бесплатно всех желающих, но наша команда будет рада оказать услуги по внедрению и обслуживанию 1С. Более подробно о наших услугах можно узнать на странице Услуги 1С или просто позвоните по телефону +7 (499) 350 29 00. Мы работаем в Москве и области.
СПРОСИТЕ в комментариях!
aklonir:
«Однако, не стоит включать индексацию по небольшим наборам данных(например, справочник Организации) – построение индекса может привести к обратному эффекту, не уменьшить скорость, а увеличит.».
Видимо ошибка: «… не уменьшить скорость, а увеличит.»
Программист 1С:
Вы правы. Спасибо большое!
Игорь:
«Внешний ключ (foreign) — 1С не использует данный вид ключей.»
Действительно, эти индексы не используются?
Программист 1С:
Из литературы вычитал что так, не верно?
Игорь:
Ну почему «Из литературы вычитал»?
Просто странно. По моему, теряются огромные возможности по использованию индексов.
Программист 1С:
Скорее всего из-за «трудностей перевода» при общении 1С с ms sql.
Согласен, интересно было бы спросить у официальных источников.
Игорь:
И не только с ms sql. У них «хранилищем» могут быть и другие СУБД. Наверное, не надо было изобретать свой язык запросов. Сейчас бы 1С была всеядной в смысле хранилища данных.
Алексей:
Не совсем так. Форэйнкеи в первую очередь нужны для обеспечения целостности данных на уровне СУБД. Так как в 1С используются составные типы данных, т.е в одном поле могут храниться ссылки на праймарикей разных таблиц справочников документов и т.д., то для ФК каждой из этих таблицы пришлось бы использовать отдельное поле, что чревато постоянной реорганизацией таблиц БД.
Роман:
Недавно столкнулся с такой проблемой: потребовалось обработать большое количество строк (около 1 млн), с последующим left join. Пакетный запрос делал table scan, затем группировал выборку по полям А,Б,С…, выполнял некий отбор. Эти поля и есть поля связи. Сгруппированная выборка связывалась с исходной таблицей, полученной в результате table scan. Рассудив, что неплохо бы проиндексировать эти поля для быстрого поиска, создал индексы в первой и в группированной таблице: индекс(А,Б,С…). Однако, быстродействие вместо того чтобы улучшиться — ухудшилось. Ввиду большого количества строк индексы строился очень долго, занимая примерно 30 процентов времени от общего времени выполнения (судя по плану запроса), а выигрыш в поиске не смог это перекрыть. Без индексов отработало быстрее.
Я что-то сделал не так или можно утверждать, что выигрыш от использования индексов возможен только в случае единичного создания индекса и последующего многократного использования для поиска?
Программист 1С:
По идее всё правильно сделали 🙂
А сколько полей и какого они типа?
Честно — однозначно сказать сложно. Сам тоже не однократно сталкивался что индексы не всегда дают прирост в производительности. Такую табличку индексов как у Вас надо еще куда то разместить…
Возможно, стоит поиграться с полями. Например, проиндексировать несколько первых. Если не трудно, отпишитесь что будет если проиндексировать их так. Возможно найти золотую середину 🙂
Роман:
Для себя вывел такое правило — индексировать временные таблицы в запросах только в случае обращения к ним более одного раза и большого количества строк. В противном случае построение индексов занимает больше времени, чем возможный выигрыш.
Недавно отметил еще такой момент. В случае, если у физической таблицы есть индексы — при поиске или отборе по проиндексированным полям, разумеется делается index range scan. Однако, если в отборе много ветвлений типа ИЛИ (OR), то вполне может быть такая ситуация, что index range scan повторится столько раз, сколько вариантов отбора… И в данном случае одноразовая выборка всей таблицы будет уместнее…
Владимир:
Такой вопрос, почему в запросах не рекомендуется в условиях использовать ИЛИ понятно, это приводит к сканированию таблиц или индекса для поиска всех включений.
Но почему предлагается замена в некоторых источниках (кажется, даже в вопросах по платформе) использовать В(), неужели трансляция запроса использует другой отбор.
Программист 1С:
Да, странная ситуация.
Приведите в пример ссылки на источники.
AlexB:
https://its.1c.ru/db/v8std#content:-2145782989:hdoc
«В основном условии оператор ИЛИ можно использовать только для последнего из используемых или единственного поля индекса, когда оператор ИЛИ можно заменить на оператор В.
ПРАВИЛЬНО:
ГДЕ
Таблица.Поле = &Значение1
ИЛИ Таблица.Поле = &Значение2
т.к. можно переписать при помощи оператора В (специально переписывать не нужно, можно оставить, как есть):
ГДЕ
Таблица.Поле В (&Значения)
НЕПРАВИЛЬНО:
ГДЕ
Таблица.Поле1 = &Значение1
ИЛИ Таблица.Поле2 = &Значение2
нельзя переписать при помощи «В»»
То есть, не то чтобы прямо рекомендуется использовать В().