MySQL: поиск строк с полем TEXT, начинающимся с запроса
У меня есть таблица и один из столбцов типа TEXT. Мне нужно искать в таблице строки с текстом, похожим на данную строку.
Поскольку строка может быть довольно длинной (скажем, 10000 байтов), я решил, что этого будет достаточно, чтобы сравнить только первые 20 байтов строки. Чтобы сделать этот поиск быстрее, я создал ключ:
KEY `description` (`description`(20))
Итак, что я хочу сделать сейчас, это один из следующих запросов:
SELECT * FROM `table` WHERE STRCMP(SUBSTRING(`description`,0,20),'string_to_compare') = 0
или же
SELECT * FROM `table` WHERE `description` LIKE 'string_to_compare%')
Обратите внимание, что я поставил только один процент в конце строки string_to_compare, чтобы сказать БД, что я хочу сравнивать только первые байты.
Я надеюсь, что мозги MySQL сделают все возможное, чтобы использовать ключ и не делать никаких дополнительных действий.
Вопросы:
- Есть ли разница, какой запрос лучше? Я лично предпочитаю второе, так как оно выглядит яснее и, надеюсь, будет лучше понимать механизм БД (MyISAM).
- Это правильно, MySQL MyISAM сделает эффективный код для этих запросов?
- Как мне поставить "%" в подготовительном заявлении PDO?
SELECT * FROM table WHERE description LIKE ":text%"
?
1 ответ
Да, есть разница. Когда
WHERE
условие вызывает функцию для значения столбца, индексы не могут быть использованы. Я не думаю, что это поймет, что вашSUBSTRING()
вызов происходит, чтобы соответствовать индексированной части текста и использовать его. С другой стороны,LIKE
специально кодируется для распознавания случаев, когда он может использовать индекс. Кроме того, если вы хотите сравнить две строки на равенство, вы должны использовать=
неSTRCMP()
например,WHERE SUBSTRING(`description`,1,20) = 'string_to_compare'
Я считаю, что это сделает эффективный запрос для
LIKE
версия.- Заполнитель не может быть в кавычках для его работы. использование
CONCAT()
объединить это:WHERE description LIKE CONCAT(:text, '%')
, Или вы можете поставить%
в конце переменной PHP, которую вы привязываете к заполнителю, и используетеWHERE description LIKE :text
,