У меня есть словарный запрос, который я хотел бы оптимизировать. Очевидно, запрос слишком длинный, так как страница результатов загружается довольно долго. Запрос выглядит следующим образом:
$var = @$_GET['q'] ;
$varup1 = strtoupper($var);
$varup = addslashes ($varup1);
$query1 = "select distinct $lang $dict WHERE
UPPER ($lang) LIKE trim('$varup')
or UPPER($lang) LIKE replace('$varup',' ','')
or replace($lang,'ß','ss') LIKE trim('$varup')
or replace($lang,'ss','ß') LIKE trim('$varup')
or replace($lang,'ence','ance') LIKE trim('$varup')
or replace($lang,'ance','ence') LIKE trim('$varup')
or UPPER ($lang) like trim(trailing 'LY' from '$varup')
or UPPER ($lang) like trim(trailing 'Y' from '$varup')
or UPPER ($lang) like trim(trailing 'MENTE' from '$varup')
or UPPER ($lang) like trim(trailing 'EMENT' from '$varup')
or UPPER ($lang) like trim(trailing 'IN' from '$varup')
Цель состоит в том, чтобы строка поиска также находила различные записи одного и того же слова или наречие прилагательного.
Стол выглядит как
или же
Например, "безупречно" также должно отображать "безупречно". "Полностью" также должен найти "полный" и наоборот.
"Feliz" также должен найти записи для "Felizmente".
Существует около двадцати подобных заменителей, которые я исключил, поскольку они не облегчают понимание вопроса.
Весь код довольно длинный, и мне интересно, смогу ли я сделать его меньше без потери функциональности. Есть идеи?
Где находится предложение FROM
в запросе?
Вызовы REPLACE
могут быть связаны: REPLACE(REPLACE(..., 'a', 'b'), 'c', 'd'). Ditto for the
REPLACE(REPLACE(..., 'a', 'b'), 'c', 'd'). Ditto for the
для звонков TRIM.
Как уже упоминалось, подходящая COLLATION
устраняет все потребности в UPPER()
и LOWER()
. Избегайте ...general...
сопоставлений, и вы получите следующее: ss
= ß
. Многие, но не все, относятся к ij
= ij
и/или oe
= œ
и/или Aa
= Å
(и т.д.); они тебе тоже нужны? Вот краткое изложение большинства ситуаций: http://mysql.rjweb.org/utf8_collations.html
Использование индекса FULLTEXT
позаботится о большинстве FULLTEXT
для которых вы тестируете, и при этом устраняет большую часть вашего кода.
Вы показываете несколько слов во втором столбце. Это просто для показа? Если вам нужно выделить слова, у вас есть другие неприятные проблемы.
Это, в одиночку, ускорит запрос примерно в 10 раз:
WHERE english LIKE 'ha%'
AND ... (whatever else you have)
То есть фильтруйте первые 2 буквы с помощью чего-то, что может использовать INDEX(english)
, в частности, LIKE 'ha%'
для слова hate
. Поскольку вы, похоже, используете PHP, не должно возникнуть никаких проблем с встраиванием этого в запрос.
Вот еще одна мысль о моей substring($word, 0, 2)
... Вместо того, чтобы специально использовать "2", посмотрим, будет ли floor(strlen($word)/2)
работать достаточно хорошо. Таким образом, "безупречно" будет протестировано как LIKE 'flawl%'
и будет работать намного быстрее, чем даже в 10 раз.
Но другая проблема. Вы рубите и слово в таблице и слово, данное? Старайтесь не рубить слово в таблице. Чтобы обсудить это далее, пожалуйста, предоставьте записи в таблице для "недостатков", "недостатков", "безупречных", безупречных "и т.д. Я не могу точно сказать, нужно ли вам пройти весь путь до" недостатков ", но различные ряды для различных форм.
Остерегайтесь некоторых очень коротких слов со странными формами. Возможно, вам нужно добавить дополнительные записи, чтобы SQL-запрос не был слишком запутанным. Они изменяют вторую букву: "ЛОЖЬ" и "ЛОЖЬ". Похоже, что есть даже общее слово, которое меняет первую букву.
field = complicated_expression
.UPPER(field) = something
не может использовать индекс. Сравнение без учета регистра устранит необходимость вUPPER
, но для других случаев вам потребуется несколько записей или какой-либо другой тип обработки.