Оптимизация запросов к словарю MySQL

0

У меня есть словарный запрос, который я хотел бы оптимизировать. Очевидно, запрос слишком длинный, так как страница результатов загружается довольно долго. Запрос выглядит следующим образом:

$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')

Цель состоит в том, чтобы строка поиска также находила различные записи одного и того же слова или наречие прилагательного.

Стол выглядит как

Изображение 174551

или же

Изображение 174551

Например, "безупречно" также должно отображать "безупречно". "Полностью" также должен найти "полный" и наоборот.

"Feliz" также должен найти записи для "Felizmente".

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

Весь код довольно длинный, и мне интересно, смогу ли я сделать его меньше без потери функциональности. Есть идеи?

  • 2
    Чтобы иметь возможность использовать индекс, вам нужно, чтобы условия были в форме field = complicated_expression . UPPER(field) = something не может использовать индекс. Сравнение без учета регистра устранит необходимость в UPPER , но для других случаев вам потребуется несколько записей или какой-либо другой тип обработки.
Теги:
optimization
performance

1 ответ

0

Где находится предложение 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-запрос не был слишком запутанным. Они изменяют вторую букву: "ЛОЖЬ" и "ЛОЖЬ". Похоже, что есть даже общее слово, которое меняет первую букву.

  • 0
    Конечно, в запросе было «от». Я пропустил это случайно, когда извлек это для примера. Ну, в случае "недостаток *" не так много записей. Есть «недостаток», «недостаток», «безупречность», «безупречность». Есть и другие случаи, когда запрос намного сложнее. Например, я не хочу, чтобы, если пользователь ищет «копию», он также перечислял перевод «полицейский», что, очевидно, не имеет смысла. В таблице нет разделенных запятыми записей. Это было просто, чтобы показать, что в нем содержится. Каждый перевод поставляется в отдельной ячейке. Спасибо за все подсказки.
  • 0
    @ user9 - это нетривиальная проблема, особенно в английском, где слова «заимствованы» из стольких разных языков.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню