Кстати (извините, я не могу вспомнить, где я это читал) оптимизатор имеет шанс получить лучший план выполнения при использовании «короткой» синтаксической формы оператора case. Хотя в конечном итоге краткая форма является просто синтаксическим сахаром, она дает оптимизатору подсказку, что все сравнения основаны на простом равенстве без использования сложных выражений.
Ваше утверждение case как данное не может быть изменено, потому что вы используете 3 разных столбца, v1, v2 и v3. Но если бы вы использовали все тот же столбец, скажем, v1, то эта модификация могла бы иногда работать лучше:
SELECT
id,
name,
case Coalesce(v1, 'dont know')
when 'Y' then 'something'
when 'K' then 'something else'
when 'dont know' then 'dont know'
else 'default'
end
from table
Ладно, может быть, это не идеально из-за ограничений, необходимых для нулевой обработки. Я просто хотел указать на возможную оптимизацию, которая может быть сделана в некоторых случаях, так как вы ищете общие советы по оптимизации.
Что бы это ни стоило, я полностью согласен, что UDF будет работать хуже. Практически повсеместное встраивание дает повышение производительности, поскольку позволяет избежать всей работы, необходимой для совершения вызова и возврата из вызова (если оптимизатор тайно не подставит его для вас).
Другая идея в этом конкретном случае заключается в том, что вы можете рассмотреть возможность использования соединения с производной таблицей, полной литеральных значений:
SELECT
id,
name,
coalesce(x.result, 'dont know')
from
table t
left join (
select 'Y', 'something'
union all select 'K', 'something else'
union all select '%', 'default'
) x (value, result) on t.v1 like x.value
Опять же, это может быть не идеально из-за способа, которым я выбрал обработку нулей с LIKE. Тем не менее, он адекватно демонстрирует технику.
Дополнительные баллы:
Тестирование всегда для того, чтобы выяснить, что дает наилучшую производительность в любой ситуации. Заполните таблицу, полную 100 000 или миллион строк, и проведите несколько тестов с запущенным профилировщиком для захвата процессора, чтения, записи и продолжительности. Предпочитаю меньше процессора / чтения в течение более низкой продолжительности.
Хотя планы выполнения часто являются хорошими руководствами, не следует полностью доверять затратам на план выполнения, поскольку они полностью игнорируют внутренние затраты на UDF и не всегда правильно выставляют компромиссы между процессором и чтением.
Обычно лучше потратить немного процессора, если он избегает даже небольшого числа операций чтения. «Постоянное сканирование», которое отображается в планах выполнения для производных таблиц, как я использовал выше, всегда будет иметь незначительную стоимость. Эта стоимость намного меньше, чем почти любое количество операций чтения, связанных с доступом к диску.