Сравнение скорости 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.