Сравнение скорости T-SQL между оператором LEFT () и LIKE - PullRequest
12 голосов
/ 31 октября 2010

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

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

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

против

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

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

Ответы [ 5 ]

13 голосов
/ 07 июля 2014

«Слева» против «Мне нравится» - всегда следует использовать «Мне нравится», когда это возможно, когда индексы реализованы, потому что «Мне нравится» не является функцией и, следовательно, может использовать любые индексы, которые вы можете иметь на данные.

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

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

8 голосов
/ 31 октября 2010

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

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

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

select * from table where name_first_char_lower = @firstletter

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

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

4 голосов
/ 17 июля 2013

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

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. Кроме того, мой общий запрос затрагивает некоторые индексы.

1 голос
/ 27 июля 2016

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

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

0 голосов
/ 23 июня 2019

пользователей Entity Framework Core

Вы можете использовать EF.Functions.Like(columnName, searchString + "%") вместо columnName.startsWith(...), и вы получите просто СРАВНИТЕЛЬНУЮ функцию в сгенерированном SQL вместо всего этого «левого» безумия!

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

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

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

...