Понедельник, 9 утра, сообщение в рабочем чате: «Все сломалось, почините».
Согласитесь, неприятная ситуация, особенно когда у вас первый месяц работы, и что-то сломалось в функционале, с которым вы раньше никогда не контактировали, и месяцами его никто не трогал.
Моя реакция в тот момент
Итак, что случилось?
Сразу после просмотра логов все становится понятно (нет): Ошибка таймаута от MS SQL сервера в модуле, который вызывается из клиентского приложения и обрабатывает документы за определенный период, передает их в систему планирования и рассчитывает различные временные и денежные показатели., после чего всё это становится доступно в другом модуле для различных оптимизаций и логистики.
Поскольку тупо увеличивать максимально возможное время выполнения процедур в настройках сервера — подход для слабаков, пришлось покопаться.
После нескольких тестов и анализов планов выполнения была найдена проблема — директория, полученная в формате xml, записывается в табличную переменную.
После очередного обновления статистики для процедуры был собран новый план выполнения, который максимально неэффективно соединяет эту переменную с основной выборкой.
Моментальное решение — переключиться на temp table, заменив символ @ на # в имени создаваемой таблицы (опускаем тот факт, что в коде они создаются по-разному, один через Decreate, другой через Create, чтобы не испортить название).
Тестируем, получаем время выполнения 1-2 секунды, довольны, заходим в продакшн, все довольны (особенно я).
Я в глазах пользователей после этой истории (по моему скромному мнению)
Какая разница?
Пока проблем нет и ситуация сводится к тому, чтобы просто сбросить куда-то нужные данные для дальнейшего использования в запросе, то разницы не будет. На просторах различных форумов можно наткнуться на вполне правильный совет — используйте временную таблицу для больших данных.Например, на сайте Microsoft вы можете найти это:
Для табличных переменных не допускается использование DDL. Поэтому, если у вас большой набор строк, который необходимо часто запрашивать, вы можете использовать #table, когда это возможно.Но помимо отсутствия DDL, разница еще серьезнее:
#СТОЛ | @СТОЛ | |
Память | Хранится в базе данных tempdb. | Хранится в базе данных tempdb, но имеет функцию передачи в виде переменной.
|
Возможность изменения структуры после создания.
| Да | Нет |
Возможность создавать индексы и ограничения.
| Да | Только первичный ключ на момент создания |
Доступ | Внутри сессии | Внутри пакета транзакций одной сессии |
Продолжительность жизни | Пока сессия активна | На данный момент действителен один пакет транзакций |
Использование в функциях | Нет | Да |
Простота использования | Можно создать и заполнить с помощью команды select to. | Не нужно проверять наличие и удалять при перезапуске кусок кода во время разработки |
Параллелизм | Да | Нет |
Имеет статистику | Да | Нет |
Под капотом
Когда-то вопрос о разнице между этими двумя механизмами привел меня к довольно старому посту.Один из отрывков гласил:
Многие планы выполнения, включающие табличные переменные, будут отображать одну строку, рассчитанную как результат их выполнения.И действительно, в плане выполнения процедуры с временной переменной было сказано — скорее всего в вашей таблице 1 запись, поэтому строим запрос так, а не иначе.Проверка свойств табличной переменной показывает, что SQL Server считает, что табличная переменная имеет нуль ряды Однако результаты, показанные в предыдущем разделе, действительно показывают точную
rows
count insys.partitions
.Проблема в том, что в большинстве случаев операторы, ссылающиеся на табличные переменные, компилируются, когда таблица пуста.
План выполнения был сгенерирован так, как если бы мы объединяли таблицу только с одной строкой, поэтому нам не нужно слишком беспокоиться об оптимизации.
Этот пункт нигде конкретно не описан и относится к категории проблем «ну вот так сделано», но это никоим образом не указывает на проблемы с продуктом.
Любой ИТ-молоток имеет свои условности и особенности, с которыми вы можете столкнуться в одной из тысячи задач.
Вместо общей суммы
Это все, что у меня есть на данный момент. Это была моя первая попытка писать, поэтому прошу не слишком критиковать за скупость языка или речевых оборотов.Я решил попробовать себя на этом пути, так как слышал, что это помогает обобщить мои знания и улучшить навыки в целом.
Спасибо за прочтение.
Теги: #программирование #оптимизация #sql #отладка #память #Microsoft SQL Server #sql-сервер #таблицы данных #ошибка #ошибка
-
Uml Для Разработчиков
19 Dec, 24 -
История Внедрения Сэд На Одном Предприятии
19 Dec, 24 -
Вышел Spb Shell 3D
19 Dec, 24 -
Как Я Нашел Умный Дом Во Власти Ботнета
19 Dec, 24