Как расшифровать операторы «Поиск ключа» и «Поиск кластеризованного индекса» в планах запросов MS SQL Server?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При анализе производительности систем на базе 1С:Предприятие одним из самых важных инструментов является план выполнения запроса MS SQL Server. Однако использование русской версии среды Management Studio (SSMS) часто вносит путаницу из-за специфического перевода технических терминов. Разберем подробно, что скрывается за названиями «Поиск ключа» и «Поиск кластеризованного индекса», как они влияют на скорость работы программы и что нужно сделать для оптимизации кода.

Поиск ключа (Key Lookup) — скрытая угроза производительности

Рассмотрим ситуацию, когда в плане запроса мы видим оператор «Поиск ключа». В оригинальной английской версии он называется Key Lookup. Это операция, которая происходит в тот момент, когда СУБД уже успешно нашла ссылку на нужную строку, используя некластеризованный индекс, но обнаружила, что в этом индексе отсутствуют некоторые поля, требуемые в блоке ВЫБРАТЬ (SELECT).

Проанализируем механику этого процесса. Когда мы выполняем запрос к базе данных 1С, SQL Server пытается найти оптимальный путь. Если у нас есть индекс по полю, участвующему в условии ГДЕ, сервер переходит к этому индексу. Однако некластеризованный индекс содержит только те поля, которые в него явно включены, и «закладку» (ссылку) на основную таблицу. Если вашему запросу нужно поле, которого нет в индексе, SQL Server вынужден для каждой найденной строки обращаться к основной таблице (кластеризованному индексу), чтобы «дозабрать» недостающие данные.

Почему это плохо? Выясним причину: если запрос возвращает сотни или тысячи строк, операция «Поиск ключа» превращается в так называемое Random I/O (случайное чтение). Вместо того чтобы прочитать данные одним сплошным блоком, сервер начинает «прыгать» по всей таблице. Это крайне медленно и сильно нагружает дисковую подсистему. В контексте 1С это часто случается, когда программист обращается к реквизитам через точку в запросе или выбирает избыточные поля.

Чтобы «вылечить» эту проблему, мы должны использовать покрывающие индексы. В терминах SQL Server это означает добавление недостающих полей в конструкцию INCLUDE индекса. В 1С мы можем добиться этого, добавляя нужные поля в состав дополнительных колонок индекса или пересматривая структуру запроса, чтобы исключить обращение к лишним данным.

Clustered Index Seek против Clustered Index Scan

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

  1. Поиск кластеризованного индекса (Clustered Index Seek): Это самый эффективный способ работы с таблицей. СУБД использует структуру B-дерева индекса, чтобы мгновенно перейти к конкретному диапазону строк. Мы читаем только те страницы данных, которые нам действительно нужны.
  2. Просмотр кластеризованного индекса (Clustered Index Scan): Несмотря на слово «поиск» в некоторых вольных переводах, Scan — это полное сканирование таблицы. SQL Server читает таблицу от начала до конца, перебирая каждую строку.

Рассмотрим подробнее ситуацию, когда Scan может появиться вместо Seek. Иногда это оправдано: у SQL Server есть так называемая «точка перегиба» (Tipping Point). Если сервер оценивает, что вам нужно прочитать более 25-30% данных всей таблицы, он сознательно выберет Scan, так как последовательное чтение всей таблицы в данном случае будет быстрее, чем постоянные переходы по ссылкам индекса.

RID Lookup: Поиск по идентификатору строки

В обсуждениях специалистов часто упоминается RID Lookup. Проанализируем, чем он отличается от обычного поиска ключа. RID Lookup — это частный случай, который возникает только в таблицах типа Heap (Куча). Это таблицы, у которых вообще нет кластеризованного индекса. В системе 1С:Предприятие такие таблицы встречаются крайне редко, так как почти все объекты (справочники, документы) имеют первичный ключ, который автоматически становится кластеризованным индексом. Однако вы можете столкнуться с RID Lookup при работе с некоторыми временными таблицами, если они не были проиндексированы должным образом.

SARGability: Почему индекс не работает?

Даже если мы создали идеальный индекс, мы можем увидеть в плане запроса Clustered Index Scan вместо ожидаемого Seek. Посмотрим на примеры ситуаций, когда запрос становится не-SARGable (то есть не позволяющим использовать аргументы поиска):

Специфика оптимизации в 1С

В контексте разработки на платформе 1С, появление операторов «Поиск ключа» или «Сканирование» часто связано с архитектурными особенностями. Разберем по шагам, на что обратить внимание:

Во-первых, это избыточный выбор полей. Если в запросе используется ВЫБРАТЬ * или выбирается очень много реквизитов «на всякий случай», вероятность получения Key Lookup возрастает в геометрической прогрессии. Старайтесь выбирать только те поля, которые действительно нужны для логики алгоритма.

Во-вторых, обратите внимание на использование механизма «Выбрать разрешенные». При проверке прав доступа на уровне записей (RLS) SQL Server вынужден обращаться к дополнительным таблицам прав. Если индексы по полям, участвующим в RLS, не оптимальны, вы увидите массовое сканирование таблиц и падение производительности всей системы.

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

Для закрепления материала, вспомним основные методы оптимизации. Если мы обнаружили Key Lookup, нам нужно:

  1. Выяснить, какие поля дочитываются из основной таблицы.
  2. Проверить, можно ли добавить эти поля в существующий некластеризованный индекс.
  3. Убедиться, что эти поля не являются строками неограниченной длины или типами ValueStorage, которые нельзя включать в индексы.

Помните, что каждый лишний «Поиск ключа» — это дополнительная нагрузка на сервер, которая при масштабировании системы может стать критической точкой отказа.

← На главную