Задавайте вопросы, мы ответим
Вы не зашли.
Недавно столкнулся с прочно забытым правилом, согласно которому MySQL применяет оператор = к строкам CHAR/VARCHAR без учета пробелов на конце:
mysql> SELECT 'a' = 'a '; +--------------+ | 'a' = 'a ' | +--------------+ | 1 | +--------------+
С учетом пробелов сравнивает LIKE:
mysql> SELECT 'a' LIKE 'a '; +-----------------+ | 'a' LIKE 'a ' | +-----------------+ | 0 | +-----------------+
Но LIKE хуже пользуется индексом на колонке url (уникальный ключ на всю длину):
mysql> EXPLAIN SELECT * FROM pages WHERE url = '/'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: pages type: const possible_keys: url key: url key_len: 258 ref: const rows: 1 Extra: 1 row in set (0.00 sec) mysql> EXPLAIN SELECT * FROM pages WHERE url LIKE '/'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: pages type: range possible_keys: url key: url key_len: 258 ref: NULL rows: 1 Extra: Using where 1 row in set (0.00 sec)
Как сравнивать строки с учетом пробелов, при этом наиболее эффективно используя индекс?
Неактивен
А в чем проблема с индексом при использовании LIKE?
Не забудь, что для CHAR и VARCHAR концевые пробелы вообще не сохраняются в базе.
Неактивен
А в чем проблема с индексом при использовании LIKE?
ref у explain поприятней выглядит. Для = - const, для LIKE - using where.
Такое впечатление, что для LIKE он не хочет использовать индекс.
Не забудь, что для CHAR и VARCHAR концевые пробелы вообще не сохраняются в базе.
Забыл
Но в данном случае проблема обратная: пробелы есть в сравниваемой с базой строке. И сравнение должно заканчиваться неудачей, если строки отличаются из-за концевых пробелов.
На практике ситуация такая: серверу приходит адрес / с пробелами на конце. Оператор = скажет, что это то же самое, что /, механизм сайта как ни в чем не бывало отдаст по адресу / главную страницу. В результате у поисковика в индексе появляется дубликат главной страницы, и сеошники падают в обморок (случай из жизни).
Неактивен
LazY написал:
Такое впечатление, что для LIKE он не хочет использовать индекс.
Это не доказательство. Должно быть по скорости так же.
Оператор = думает, что вдруг там был тоже пробел, но съелся при записи в базу.
Неактивен
Это не доказательство. Должно быть по скорости так же.
По скорости и так 0.00, и так 0.00 - таблица 100 записей
Неактивен
Просто анализ путей запроса - важная часть механизма сайта, срабатывает при каждом запросе. Хотелось сделать ее максимально быстрой.
Если LIKE нормально - то и ладно.
Неактивен
Сделай миллион записей и проверь. Вижу только то, что = делает проверку на точное совпадение, а LIKE на range. Хотя очевидно, что range достаточно узкий, это интересный вопрос почему range.
Кстати, у тебя может быть еще одна проблема. В данном случае с большими и маленькими буквами:
Неактивен
это интересный вопрос почему range
Видимо, потому что не точное равенство. LIKE по правой части оптимизатор наверняка рассматривает как range, а частный случай, когда LIKE без процентов, он отдельно не учитывает.
Кстати, для = BINARY тоже показывает range.
Насчет использования индекса. Дело тут, похоже, в наборе колонок для SELECT.
Если вместо SELECT * сделать SELECT COUNT(*), то и =, и LIKE, и = BINARY дают Using where; Using index.
По скорости все оказались примерно одинаковыми.
Кстати, у тебя может быть еще одна проблема. В данном случае с большими и маленькими буквами:
Да. Но ее решение - это вопрос отдельный.
Неактивен