Сравнение скорости T-SQL между оператором LEFT() и LIKE

Я создаю поисковик результатов на основе первой буквы определенного столбца nvarchar, а не обычного, который обычно содержит количество результатов.

И я не сталкиваюсь с проблемой, следует ли фильтровать результаты с помощью оператора LIKE или равенства (=).

select *
from table
where name like @firstletter + '%'

против.

select *
from table
where left(name, 1) = @firstletter

Я попытался найти сеть для сравнения скорости между ними, но трудно найти какие-либо результаты, так как большинство результатов поиска связаны с функцией LEFT JOINs, а не LEFT.

Ответ 1

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

Если это запрос, который вы будете делать много, вы должны рассмотреть другой (индексированный) столбец, который содержит нижнюю нижнюю первую букву name и установить ее с помощью триггера insert/update.

Это за счет минимального увеличения хранилища сделает этот запрос ослепляюще быстрым:

select * from table where name_first_char_lower = @firstletter

Это потому, что большинство баз данных читаются гораздо чаще, чем написано, и это будет амортизировать стоимость вычисления (только для записи) во всех чтениях.

Он вводит избыточные данные, но это нормально для производительности, если вы понимаете (и смягчаете, как в этом предложении) последствия и нуждаетесь в дополнительной производительности.

Ответ 2

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

"Слева", с другой стороны, является функцией и, следовательно, не может использовать индексы. Эта веб-страница описывает различия в использовании с некоторыми примерами. Это означает, что SQL-сервер должен оценивать функцию для каждой возвращаемой записи.

"Подстрока" и другие подобные функции также являются виновниками.

Ответ 3

У меня был аналогичный вопрос, и я провел тесты на обоих. Вот мой код.

where (VOUCHER like 'PCNSF%'
    or voucher like 'PCLTF%'
    or VOUCHER like 'PCACH%'
    or VOUCHER like 'PCWP%'
    or voucher like 'PCINT%')

Возвращено 1434 строки за 1 мин 51 секунду.

против

where (LEFT(VOUCHER,5) = 'PCNSF'
    or LEFT(VOUCHER,5)='PCLTF'
    or LEFT(VOUCHER,5) = 'PCACH'
    or LEFT(VOUCHER,4)='PCWP'
    or LEFT (VOUCHER,5) ='PCINT')

Возвращено 1434 строки за 1 мин. 27 секунд

Мои данные быстрее с левым 5. Как и в стороне, мой общий запрос действительно поражает некоторые индексы.

Ответ 4

Я всегда предлагал использовать такой же оператор, когда столбец поиска содержит индекс. Я протестировал вышеуказанный запрос в своей производственной среде с помощью select count (column_name) из table_name, где left (column_name, 3) = 'AAA' ИЛИ ​​left (column_name, 3) = 'ABA' OR... до 9 OR clause. Мой счет отображает 7301477 записей с 4 секундами влево и 1 секунду, как например i.e, где column_name, например, "AAA%" или "Column_Name", например "ABA%" или... до 9 подобных предложений.

Вызов функции в том, что предложение не является лучшей практикой. См. http://blog.sqlauthority.com/2013/03/12/sql-server-avoid-using-function-in-where-clause-scan-to-seek/

Ответ 5

Пользователи Entity Framework Core

Вы можете использовать EF.Functions.Like(columnName, searchString + "%") вместо columnName.startsWith(...) и вы получите просто функцию LIKE в сгенерированном SQL вместо всего этого "левого" безумия!

В зависимости от ваших потребностей вам, вероятно, потребуется предварительно обработать searchString.

Смотрите также https://github.com/aspnet/EntityFrameworkCore/issues/7429

Эта функция отсутствует в Entity Framework (не основной) EntityFunctions поэтому я не уверен, как это сделать для EF6.