Я ищу потенциально более быстрый способ сделать эту проверку:
NOT LIKE '%[^0-9]%'
Это проверяет, чтобы все символы были числами (см. описание шаблона T-SQL)
Есть ли более быстрый способ сделать это в Microsoft SQL Server (T-SQL)?
Полный контекст является частью оператора CASE/WHEN в части выбора запроса с переменным размером:
Select DATEADD(dd, CAST(CASE WHEN a.dateDuration NOT LIKE '%[^0-9]%' THEN a.Duration ELSE 1 END AS INT), a.StartDate) AS 'ourEndDate'
В приведенном выше примере a является псевдонимом таблицы. Столбец a.dateDuration является столбцом varchar с нулевым значением. (Настоящие имена сущностей заменены по служебным причинам).
Действительно, варианты этого повторяются в различных операторах «UNION ALL», поэтому, если бы это можно было сделать быстрее, это могло бы значительно ускорить запрос.
Оператор NOT LIKE
предположительно относительно медленный.
Версия базовой базы данных — SQL Server 2012.
Есть небольшой шанс, что PATINDEX('%[^0-9]%', textValue) = 0
может работать по-другому, поскольку SQL может оптимизировать %
в одном случае, но не в другом. Добавление COLLATE Latin1_General_Bin
также может привести к небольшому улучшению, поскольку позволит избежать потенциальных накладных расходов на эквивалентность регистра или символов с диакритическими знаками. Оба являются предположениями и потребуют тестирования.
Какой именно здесь контекст? Это в WHERE
? Проверка того, является ли значение допустимым целочисленным значением, никогда не будет иметь возможности SARGable; потребуется полное сканирование. Если ваши данные не должны содержать символов, отличных от цифр, почему бы не использовать целочисленный тип данных?
Не существует «более быстрого способа» проверить, соответствует ли каждое отдельное значение шаблону подстановочных знаков или может быть преобразовано в определенный тип. SQL Server должен попробовать/проверить каждое значение, поэтому он должен проверять каждую строку. Теперь вы можете рассмотреть вычисляемый столбец (например, IntegerValue AS (TRY_CONVERT(int, col))
), проиндексировать его и оплатить эту стоимость во время вставки, но вы должны заплатить за это.
Примечание: я не думаю, что существовала SSMS 15; текущая версия — SSMS 18, до этого были 17 и 16, а затем 2014 (которая не была известна как SSMS 15).
Должно быть довольно быстро. У вас есть конкретные проблемы с производительностью? (Если да, дайте нам немного больше контекста, как сказал Аарон, может потребоваться выполнить проверку в INSERT
и UPDATE
время и проиндексировать результат, чтобы избежать сканирования таблицы и т. д.)
В этом контексте выполнение оператора LIKE / NOT LIKE почти наверняка не является проблемой. Если ваш запрос медленный, сначала подумайте, сколько строк вы возвращаете и выполняете ли вы полное сканирование таблиц для поиска интересных строк.
Здесь похоже, что вы только пытаетесь отформатировать/настроить свой окончательный результат - если вы считаете, что SQL здесь слишком медленный, вы можете выполнить эту обработку на стороне сервера приложений, поскольку это не является частью выборки данных с диска.
Если это подзапрос, покажите весь запрос.
Что-то вроде
try_convert
может быть быстрее, но оно не будет обрабатывать строки с миллиардами символов и допускает отрицательный знак (-
) для значенийint
. (См. разглагольствование о производительности.) В стороне: База данных реализует функциональность. Все, что вы включаете в SSMS, — это просто шум в отношении пользовательского интерфейса.