Что такое план запроса и как его посмотреть
Что проверяют
Умеете ли вы диагностировать медленный запрос из приложения, а не только писать LINQ. Проверяют знание инструментов сервера баз данных и понимание того, что через объектную модель в базу уходит не тот текст, который вы пишете в консоли.
Как отвечать
План запроса это дерево операторов, по которому сервер выполняет запрос: способ доступа к данным (сканирование, поиск по индексу, обращение за недостающими столбцами), способ соединения (вложенные циклы, хеш, слияние), сортировки и агрегации. Различают оценочный план, который строится без выполнения, и фактический, где рядом с оценками стоят реальные числа строк и время.
Как получить:
- В графическом клиенте: показать оценочный план либо включить фактический и выполнить запрос.
- Из T-SQL: SET SHOWPLAN_XML ON возвращает оценочный план и запрос не выполняет; SET STATISTICS XML ON выполняет запрос и отдаёт фактический. Обе команды должны идти отдельной пачкой.
- На проде: хранилище планов и представления кэша планов, чтобы увидеть реальный запуск, а не локальную попытку воспроизвести.
Из C# берут не выдуманный SQL, а настоящий: EF Core умеет отдать текст запроса и логировать команды. Дальше важны две вещи. Типы параметров влияют на план: строковый параметр в Unicode против столбца в однобайтовой кодировке даёт неявное преобразование и сканирование вместо поиска. И подстановка параметров: план закешировался под редкое значение и работает плохо на обычных.
Где спотыкаются
Называют оценочный план фактическим. Команда, которая ничего не выполняет, показывает только предположения оптимизатора, а расхождение оценки и факта видно лишь в фактическом плане, и чаще всего именно оно объясняет тормоза.
Проверяют запрос голым SQL в клиенте и переносят вывод на приложение. Через объектную модель уходит другой текст, с параметрами, другими опциями сессии и другим кэшированным планом, поэтому воспроизводить надо ровно то, что шлёт приложение.
Видят подсказку об отсутствующем индексе и создают предложенный индекс не глядя. Подсказка учитывает один запрос, любит широкие списки включаемых столбцов и часто дублирует уже существующий индекс, а платить за это будет каждая запись в таблицу.