Skip to content

9 признаков того, что ваш T-SQL может не пройти проверку кода

Пересказ статьи Brent Ozar. 9 Signs Your T-SQL Might Fail a Code Review


Трудно установить абсолютные правила типа: "Фичу X нельзя использовать ни в коем случае."

Однако имеется несколько вещей, которые включают тревожный звоночек, когда я их вижу. Обычно, когда я начинаю задавать больше вопросов об использовании этих конкретных функций, мне отвечают "О, я не знал, что была проблема." Поскольку у нас более широкое обсуждение, это приводит к тому фрагменту кода, который не проходит проверку и возвращается на доработку.

  1. Соединение с табличнозначными функциями пользователя: Если это многооператорная функция, то что она делает, не показывается в планах выполнения, и является однопотоковым построчным выполнением. Я открою план только для того, чтобы двойным щелчком проверить, является она многооператорной или встроенной, и не дай бог она вызывает другую функцию.

  2. Соединение с табличными переменными: даже в 2019 с его улучшенной оценкой числа строк, табличные переменные все еще не имеют статистики на свое содержимое, а вставка данных в них является однопотоковой. Есть несколько крайних случаев использования, которые мы обсуждали в Основы TempDB, особенно в плане сокращения перекомпиляций, но обычно, когда я вижу табличную переменную в коде, это происходит по причине незнания их слабостей.

  3. CROSS JOIN: конечно, должны быть веские причины, почему вы захотели получить каждую строку из таблицы без какой бы то ни было фильтрации, но это довольно необычно. Эти два слова включают тревожный звоночек, который заставляет меня посмотреть на это более внимательно.

  4. Множественные соединения с одним и тем же CTE: CTE может быть замечательным, хотя временная таблица часто для этого лучше подходит. При проверке кода флажок поднимают, когда видят множественные ссылки на один и тот же CTE, например, FROM cte JOIN cte JOIN cte, каждый с другим алиасом. Этот CTE будет показан множество раз в плане выполнения, вызывая повторные обращения в лежащим в основе таблицам.

  5. Шаблон дизайна кухонной мойки: WHERE (CustomerId = @CustomerId OR @CustomerId IS NULL) сложно для оптимизации в SQL Server, и мы обычно меняем это на динамический SQL или используем хинты RECOMPILE.

  6. SELECT (что-то) INTO #TempTable: Мне нравятся временные таблицы, и я думаю, что у них просто плохая репутация, но даже SELECT INTO может иметь преимущества по сравнению с явным созданием таблицы. Однако, когда я вижу SELECT INTO, это обычно означает торопливую работу, и некто не захотел потратить время на написание CREATE TABLE и выписывание всех типов данных. Например, во время недавней проверки автор запроса копировал всю таблицу в TempDB, а затем фильтровал там строки - думая, что это минимизирует объем работы, которая выполнялась в базе данных пользователя.

  7. Создание индексов на временной таблице: Это вроде звучит хорошо - и, в конце концов, кто не любит индексы? - но в большинстве случаев, когда я вижу это и начинаю задавать вопросы, то получаю подобные ответы: "Я просто догадался, что индекс может помочь." Это заставляет нас потратить немного больше времени на эксперименты, а также приводит к обучающим моментам того, как это влияет на кэширование временной таблицы.

  8. WITH (NOLOCK): Я храню демонстрационный пример того, как это дает случайные результаты. И я знаю, что вам трудно в это поверить, но не тем, кто читает мой блог. Имеются ситуации, когда случайные результаты действительно хороши, но в большинстве случаев, когда я вижу этот красный флажок и спрашиваю, оказывается, что автор запроса просто не знал, насколько опасен может быть этот хинт. Бонусные баллы за попытку использовать его в операторе UPDATE.

  9. BEGIN TRAN & COMMIT без обработки ошибок. Когда я вижу это, то спрашиваю: "Итак, вы выполняете явную транзакцию, поскольку для вас важно, чтобы все фиксировалось или ничего, правильно? И вы ожидаете, что если время от времени возникает сбой транзакции, вы хотите откатить изменения, правильно? Итак, э-э, что произойдет с вашим приложением, если это случится?" Если вы озаботились тем, чтобы задать транзакцию в вашей базе данных, тогда нужно пойти дальше и указать также, как обрабатывать ошибки. Публикация Erland Sommarskog об обработке ошибок и транзакциях - хорошее место для начала.


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

Обратные ссылки

Нет обратных ссылок

Комментарии

Показывать комментарии Как список | Древовидной структурой

Нет комментариев.

Автор не разрешил комментировать эту запись

Добавить комментарий

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Form options

Добавленные комментарии должны будут пройти модерацию прежде, чем будут показаны.