Относительная производительность в SQLServer подстроки по сравнению с комбинацией Right-Left

Это вопрос, основанный на производительности, а не "Я не понимаю" или "лучший способ".

У меня есть поле varchar в базе данных SQLServer, которая гарантированно длиннее 7 символов. Мне нужно извлечь поле char (4), состоящее из 2, 3, 4 и 5 символов в varchar.

Например, если varchar имел значение 1234567890, я бы искал часть 2345.

Есть ли преимущество в производительности для использования подстроки над списком справа налево?

SELECT SUBSTRING(account,2,4) FROM payment

или

SELECT RIGHT(LEFT(account,5),4) FROM payment

Я заметил небольшое преимущество, используя правую левую сторону таблицы с 1,760,335 записями, но я не уверен, связано ли это с кешированием запросов и т.п.

UPDATE Я сделал немного больше домашней работы. Кажется, что в этом случае правые-левые в конечном счете выполняются как правая подстрока. Это правило? или это просто способ, которым SQLServer решил скинуть этот конкретный кот? alt text

Ответ 1

+1 для интересного вопроса. Ваша оценка того, что SQL Server может существенно изменить каждый оператор с помощью оптимизации, вероятно, точна; так же, как и ваша оценка, что в таком большом наборе SQL Server может кэшировать один запрос лучше другого.

На ум приходят еще две вещи, которые могут быть (смутно) релевантными:

  • Потребление памяти; Мне было бы любопытно, если комбинация LEFT/RIGHT потребляет немного больше памяти. Теоретически возвращаемое значение первой функции должно быть сохранено так, чтобы оно могло быть передано во вторую функцию, хотя один и тот же регистр мог использоваться снова и снова.

  • Проверка границ. Varchar - это в основном указатель на начало char [] с двумя дополнительными байтами для указания длины. Это предполагает, что при доступе к значению индексом необходимо выполнить некоторую проверку границ, посмотрев на значение, содержащееся в этих двух байтах, чтобы убедиться, что оно не находится за пределами допустимого диапазона.

SQL Server также очень прощает, делая запросы за пределами строки с символами и varchars. Следующий код будет работать без ошибок.

DECLARE @Test varchar(50);
SET @Test = 'Hello World';
SELECT substring(@Test, 2, 4);
SELECT substring(@Test, 2000, 5000);

Так будет:

SELECT right(left(@test, 500), 400);

Я предполагаю, что объяснение для ответа на ваш вопрос лежит в чем-то связанном; к сожалению, я не знаю знаю ответ на ваш вопрос.

Мне было бы любопытно, если бы вы получили те же результаты производительности, что и более длинная строка, или char по сравнению с varchar. Эти тесты могут дать больше информации о внутренних компонентах SQL Server.