Вопрос

При использовании SQL есть ли какие-либо преимущества использования = в WHERE предложение вместо LIKE?

Без каких-либо специальных операторов, LIKE и = это одно и то же, верно?

Это было полезно?

Решение

Разные операторы

LIKE и = это разные операторы.Большинство ответов здесь сосредоточены на поддержке подстановочных знаков, что является не единственным различием между этими операторами!

= является оператором сравнения, который оперирует числами и строками.При сравнении строк оператор сравнения сравнивает целые строки.

LIKE является строковым оператором , который сравнивает символ за символом.

Чтобы усложнить ситуацию, оба оператора используют сопоставление что может оказать важное влияние на результат сравнения.

Мотивирующий Пример

Давайте сначала приведем пример, в котором эти операторы дают явно разные результаты.Позвольте мне процитировать руководство по MySQL:

Согласно стандарту SQL, LIKE выполняет сопоставление для каждого символа, таким образом, он может выдавать результаты, отличные от оператора сравнения =:

mysql> SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
+-----------------------------------------+
| 'ä' LIKE 'ae' COLLATE latin1_german2_ci |
+-----------------------------------------+
|                                       0 |
+-----------------------------------------+
mysql> SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
+--------------------------------------+
| 'ä' = 'ae' COLLATE latin1_german2_ci |
+--------------------------------------+
|                                    1 |
+--------------------------------------+

Пожалуйста, обратите внимание, что эта страница руководства по MySQL называется Функции сравнения строк, и = не обсуждается, что подразумевает, что = строго говоря, это не функция сравнения строк.

Как это = Работать?

В Стандарт SQL § 8.2 описывает , как = сравнивает строки:

Сравнение двух символьных строк определяется следующим образом:

a) Если длина в символах X не равна длине в символах типа Y, тогда более короткая строка эффективно заменяется, для целей сравнения, копией самой , которая была расширена до длины более длинной строка путем конкатенации справа от одного или нескольких полей ввода символы, где символ поля выбирается на основе CS.Если CS имеет нет атрибута коврик, то коврик символ зависит от реализации персонаж отличается от любого символов в набор символов X и y, которые собирает меньше чем любую строку под CS.В противном случае символом pad является a .

b) Результат сравнения X и Y задается с помощью последовательности сопоставления CS.

c) В зависимости от последовательности сортировки две строки могут сравниваться как равные, даже если они имеют разную длину или содержат разные последовательности символов.Когда операции MAX, MIN, DISTINCT, ссылки на столбец группировки и Операторы ОБЪЕДИНЕНИЯ, ИСКЛЮЧЕНИЯ и ПЕРЕСЕЧЕНИЯ относятся к символам строки, конкретное значение, выбранное этими операциями из набор таких равных значений зависит от реализации.

(Курсив мой добавлен.)

Что это значит?Это означает, что при сравнении строк = operator - это всего лишь тонкая оболочка вокруг текущей сортировки.Сопоставление - это библиотека, которая имеет различные правила для сравнения строк.Вот пример того, как двоичная сортировка из MySQL:

static int my_strnncoll_binary(const CHARSET_INFO *cs __attribute__((unused)),
                               const uchar *s, size_t slen,
                               const uchar *t, size_t tlen,
                               my_bool t_is_prefix)
{
  size_t len= MY_MIN(slen,tlen);
  int cmp= memcmp(s,t,len);
  return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
}

Эта конкретная сортировка выполняется для сравнения побайтов (именно поэтому она называется "двоичной" — она не придает строкам никакого особого значения).Другие параметры сортировки могут обеспечить более продвинутые сравнения.

Например, вот Параметры сортировки в формате UTF-8 это поддерживает сравнения без учета регистра.Код слишком длинный, чтобы вставлять его сюда, но перейдите по этой ссылке и прочитайте текст my_strnncollsp_utf8mb4().Эта сортировка может обрабатывать несколько байтов одновременно и может применять различные преобразования (например, сравнение без учета регистра).В = оператор полностью абстрагирован от капризов сортировки.

Как это LIKE Работать?

В Стандарт SQL § 8.5 описывает , как LIKE сравнивает строки:

В <predicate>

M LIKE P

является истинным, если существует разбиение M на подстроки такое, что:

i) Подстрока из M представляет собой последовательность из 0 или более непрерывных <character representation="">s из M и каждая <character representation=""> из M является частью ровно одной подстроки.

ii) Если спецификатор i-й подстроки P является произвольным спецификатором символа, i-я подстрока M является любой одиночной <character representation="">.

iii) Если спецификатор i-й подстроки P является произвольной строкой спецификатор, то i-я подстрока M представляет собой любую последовательность из 0 или более <character representation="">s.

iv) Если спецификатор i-й подстроки P не является ни спецификатором произвольного символа, ни спецификатором произвольной строки, тогда i-я подстрока M равна этой подстроке спецификатор в соответствии с последовательностью сопоставления the <like predicate="">, без добавления <space> символов к M, и имеет ту же длину, что и эта подстрока спецификатор.

v) Количество подстрок в M равно количеству спецификаторов подстрок в P.

(Курсив мой добавлен.)

Это довольно многословно, так что давайте разберем это по порядку.Пункты ii и iii относятся к подстановочным знакам _ и %, соответственно.Если P не содержит никаких подстановочных знаков, тогда применяется только пункт iv.Это тот случай, представляющий интерес со стороны OP.

В этом случае он сравнивает каждую "подстроку" (отдельные символы) в M против каждой подстроки в P используя текущую сортировку.

Выводы

Суть в том, что при сравнении строк, = сравнивает всю строку целиком, в то время как LIKE сравнивает по одному символу за раз.В обоих сравнениях используются текущие параметры сортировки.Это различие в некоторых случаях приводит к разным результатам, о чем свидетельствует первый пример в этом посте.

Какой из них вам следует использовать?Никто не может вам этого сказать — вам нужно использовать тот, который подходит для вашего варианта использования.Не проводите преждевременную оптимизацию, переключая операторы сравнения.

Другие советы

Оператор equals (=) - это "оператор сравнения сравнивает два значения на равенство". Другими словами, в инструкции SQL он не вернет значение true, если обе части уравнения не равны.Например:

SELECT * FROM Store WHERE Quantity = 200;

Оператор LIKE "реализует сравнение соответствия шаблону", которое пытается сопоставить "строковое значение со строкой шаблона, содержащей символы подстановки". Например:

SELECT * FROM Employees WHERE Name LIKE 'Chris%';

LIKE обычно используется только со строками, а equals (я полагаю) работает быстрее.Оператор equals обрабатывает символы подстановки как буквенные символы.Разница в возвращаемых результатах заключается в следующем:

SELECT * FROM Employees WHERE Name = 'Chris';

И

SELECT * FROM Employees WHERE Name LIKE 'Chris';

Вернул бы тот же результат, хотя использование LIKE обычно заняло бы больше времени из-за совпадения с шаблоном.Однако,

SELECT * FROM Employees WHERE Name = 'Chris%';

И

SELECT * FROM Employees WHERE Name LIKE 'Chris%';

Вернул бы разные результаты, где использование "=" приводит только к результатам с возвращением "Chris%", а оператор LIKE вернет все, что начинается с "Chris".

Надеюсь, это поможет.Можно найти некоторую полезную информацию здесь.

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

= следует использовать, если вы хотите точных совпадений, и это будет быстрее.

Этот сайт объясняет LIKE

Это копия / вставка другого моего ответа на вопрос SQL 'нравится' vs '=' производительность:

Личный пример использования mysql 5.5:У меня было внутреннее соединение между 2 таблицами, одной из 3 миллионов строк и одной из 10 тысяч строк.

При использовании лайка к индексу, как показано ниже (без подстановочных знаков), это занимало около 30 секунд:

where login like '12345678'

используя 'explain', я получаю:

enter image description here

При использовании '=' в том же запросе это заняло около 0,1 секунды:

where login ='12345678'

Используя 'explain', я получаю:

enter image description here

Как вы можете видеть, like полностью отменен поиск по индексу, поэтому запрос занял в 300 раз больше времени.

Одно отличие - помимо возможности использовать подстановочные знаки с LIKE - заключается в конечных пробелах:Оператор = игнорирует пробел в конце, но LIKE этого не делает.

Зависит от системы базы данных.

Как правило, без специальных символов, yes, = и LIKE - это одно и то же.

Однако некоторые системы баз данных могут по-разному обрабатывать параметры сортировки разными операторами.

Например, в MySQL сравнения с = по строкам по умолчанию всегда нечувствительны к регистру, поэтому LIKE без специальных символов - это то же самое.В некоторых других СУБД LIKE не чувствителен к регистру, в то время как = - нет.

В этом примере мы считаем само собой разумеющимся, что varcharcol не содержит '' и не иметь ни одной пустой ячейки против этого столбца

select * from some_table where varcharCol = ''
select * from some_table where varcharCol like ''

Первый приводит к выводу строки 0, в то время как второй показывает весь список.= является регистром строгого соответствия, в то время как like действует как фильтр.если фильтр не имеет критериев, все данные являются допустимыми.

like - в силу своего назначения работает немного медленнее и предназначен для использования с varchar и подобными данными.

Если вы ищете точное совпадение, вы можете использовать оба варианта, = и LIKE.

Использование "=" в этом случае немного быстрее (поиск точного соответствия) - вы можете проверить это самостоятельно, дважды выполнив один и тот же запрос в SQL Server Management Studio, один раз используя "=", один раз используя "НРАВИТСЯ", а затем используя "Запрос" / "Включить фактический план выполнения".

Выполните два запроса, и вы должны увидеть свои результаты дважды, плюс два фактических плана выполнения.В моем случае они были разделены на 50% против50%, но план выполнения "=" имеет меньшую "предполагаемую стоимость поддерева" (отображается при наведении курсора мыши на крайнее левое поле "ВЫБРАТЬ") - но опять же, на самом деле это не такая уж большая разница.

Но когда вы начнете поиск с использованием подстановочных знаков в вашем выражении LIKE, производительность поиска снизится.Поиск "LIKE Mill%" все еще может быть довольно быстрым - SQL Server может использовать индекс по этому столбцу, если таковой имеется.Поиск "LIKE %expression%" ужасно медленный, поскольку единственный способ, которым SQL Server может удовлетворить этот поиск, - это выполнить полное сканирование таблицы.Так что будьте осторожны со своими ЛАЙКАМИ !

Марк

Использование = позволяет избежать конфликтов подстановочных знаков и специальных символов в строке при построении запроса во время выполнения.

Это облегчает жизнь программисту, поскольку не нужно экранировать все специальные подстановочные знаки, которые могут проскальзывать в предложении LIKE и не приводить к желаемому результату.В конце концов, = - это сценарий использования в 99% случаев, было бы больно каждый раз избегать их.

закатывает глаза в 90 - е

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

Чтобы ответить на первоначальный вопрос, касающийся производительности, все сводится к использование индекса.Когда происходит простое сканирование таблицы, "LIKE" и "=" являются идентичный.Когда задействованы индексы, это зависит о том, как формируется предложение LIKE.Более конкретно, каково расположение подстановочных знаков?


Рассмотрим следующее:

CREATE TABLE test(
    txt_col  varchar(10) NOT NULL
)
go

insert test (txt_col)
select CONVERT(varchar(10), row_number() over (order by (select 1))) r
  from master..spt_values a, master..spt_values b
go

CREATE INDEX IX_test_data 
    ON test (txt_col);
go 

--Turn on Show Execution Plan
set statistics io on

--A LIKE Clause with a wildcard at the beginning
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '%10000'
--Results in
--Table 'test'. Scan count 3, logical reads 15404, physical reads 2, read-ahead reads 15416, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index SCAN is 85% of Query Cost

--A LIKE Clause with a wildcard in the middle
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '1%99'
--Results in
--Table 'test'. Scan count 1, logical reads 3023, physical reads 3, read-ahead reads 3018, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost for test data, but it may result in a Table Scan depending on table size/structure

--A LIKE Clause with no wildcards
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '10000'
--Results in
--Table 'test'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost
GO

--an "=" clause = does Index Seek same as above
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col = '10000'
--Results in
--Table 'test'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost
GO


DROP TABLE test

Также может быть незначительная разница в создании плана запроса при использовании "=" против "LIKE".

Помимо подстановочных знаков, разница между = И LIKE будет зависеть как от типа SQL server, так и от типа столбца.

Возьмем этот пример:

CREATE TABLE testtable (
  varchar_name VARCHAR(10),
  char_name CHAR(10),
  val INTEGER
);

INSERT INTO testtable(varchar_name, char_name, val)
    VALUES ('A', 'A', 10), ('B', 'B', 20);

SELECT 'VarChar Eq Without Space', val FROM testtable WHERE varchar_name='A'
UNION ALL
SELECT 'VarChar Eq With Space', val FROM testtable WHERE varchar_name='A '
UNION ALL
SELECT 'VarChar Like Without Space', val FROM testtable WHERE varchar_name LIKE 'A'
UNION ALL
SELECT 'VarChar Like Space', val FROM testtable WHERE varchar_name LIKE 'A '
UNION ALL
SELECT 'Char Eq Without Space', val FROM testtable WHERE char_name='A'
UNION ALL
SELECT 'Char Eq With Space', val FROM testtable WHERE char_name='A '
UNION ALL
SELECT 'Char Like Without Space', val FROM testtable WHERE char_name LIKE 'A'
UNION ALL
SELECT 'Char Like With Space', val FROM testtable WHERE char_name LIKE 'A '
  • Используя MS SQL Server 2012, конечные пробелы будут проигнорированы при сравнении, за исключением LIKE когда тип столбца равен VARCHAR.

  • Используя MySQL 5.5, конечные пробелы будут проигнорированы для =, но не для LIKE, оба с CHAR и VARCHAR.

  • Используя PostgreSQL 9.1, пробелы значимы с обоими = и LIKE используя VARCHAR, но не с CHAR (см. Документация).

    Поведение с LIKE также отличается с CHAR.

    Используя те же данные, что и выше, используя явный CAST по названию столбца также имеет значение:

    SELECT 'CAST none', val FROM testtable WHERE char_name LIKE 'A'
    UNION ALL
    SELECT 'CAST both', val FROM testtable WHERE
        CAST(char_name AS CHAR) LIKE CAST('A' AS CHAR)
    UNION ALL
    SELECT 'CAST col', val FROM testtable WHERE CAST(char_name AS CHAR) LIKE 'A'
    UNION ALL
    SELECT 'CAST value', val FROM testtable WHERE char_name LIKE CAST('A' AS CHAR)
    

    Это возвращает только строки для "ПРИВЕДЕННЫХ обоих" и "ПРИВЕДЕННОГО столбца".

К ключевому слову LIKE, несомненно, прилагается "ценник производительности".Тем не менее, если у вас есть поле ввода, которое потенциально может включать символы подстановки для использования в вашем запросе, я бы рекомендовал использовать LIKE только если входные данные содержат одну из подстановочных карт.В противном случае используйте стандарт, равный сравнению.

С наилучшими пожеланиями...

На самом деле все сводится к тому, что вы хотите, чтобы запрос выполнял.Если вы имеете в виду точное совпадение, то используйте =.Если вы имеете в виду более размытое совпадение, то используйте LIKE .Говорить то, что вы имеете в виду, обычно является хорошей политикой в отношении кода.

В Oracle ‘like’ без подстановочных знаков вернет тот же результат, что и ‘equals’, но может потребовать дополнительной обработки. По словам Тома Кайта, Oracle будет рассматривать ‘like’ без подстановочных знаков как ‘equals’ при использовании литералов, но не при использовании переменных bind.

= и LIKE это не одно и то же;

  1. = соответствует точной строке
  2. LIKE соответствует строке, которая может содержать подстановочные знаки (%)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top