Между этими тремя запросами существует большая разница:
a) SELECT * FROM u WHERE u.name LIKE "George%"
b) SELECT * FROM u WHERE u.name LIKE "%George"
c) SELECT * FROM u WHERE u.name LIKE "%George%"
a) Первый будет использовать индекс u.name (если он есть) и будет очень быстрым.
b) Второй не сможет использовать какой-либо индекс для u.name, но есть способы обойти это довольно легко.
Например, вы можете добавить другое поле nameReversed
в таблице, где хранится REVERSE(name)
.С индексом в этом поле запрос будет переписан как (и будет таким же быстрым, как и первый):
b2) SELECT * FROM u WHERE u.nameReversed LIKE REVERSE("%George")
c) Третий запрос представляет наибольшую сложность, поскольку ни один издва предыдущих индекса будут полезны, и запрос будет сканировать всю таблицу.Альтернативы:
Использование выделенного для решения таких проблем (поиск по «полнотекстовому поиску»), например, Sphinx.См. Этот вопрос о SO с более подробной информацией: Какие лучшие методы поиска для поиска записей
Если ваше поле имеет только имена (или другой ограниченный набор слов,скажем, несколько сотен разных слов), вы можете создать еще одну вспомогательную таблицу с этими именами (словами) и хранить только внешний ключ в таблице u
.
Если не по курсу, это не так, и у вас есть десяткитысячи или миллионы разных слов или поле содержит целые фразы, а затем решить проблему со многими вспомогательными таблицами, это все равно, что создать для себя инструмент полнотекстового поиска.Это хорошее упражнение, и вам не придется использовать Sphinx (или другой) помимо СУБД, но это не тривиально.