Как я могу ускорить этот MySQL Query, где предложения WHERE уже проиндексированы? - PullRequest
0 голосов
/ 01 июня 2018

У меня есть следующий запрос, который обрабатывается от 300 мс до 450 мс.

Таблица имеет около 300 тыс. Строк и имеет размер 46 МБ.

У меня созданы следующие индексы:

  1. Index1 - страна и страна
  2. Index2 - город и городabbr
  3. Index3 - город и cityabbr и страна и страна iso


SELECT latitude, longitude, timezone
FROM geolocate WHERE
(LCASE(country) = 'cambodia' OR LCASE(countryiso) = 'cambodia')
AND
(
(LCASE(city) = 'kaôh préab' OR LCASE(cityabbr) = 'kaôh préab')
);

300 мс Я чувствую, что это слишком много времени, но я не уверен, как это ускорить.

Я пытался создатьИндексы отдельных столбцов безрезультатны.

Если кто-нибудь может предложить какую-либо помощь, я буду очень признателен.

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

(О. Джонс объяснил, как избавиться от LCASE; я буду обращаться к OR в контексте данного запроса.)

План A: Ваше приложение должно распознавать, являются ли имена полными или сокращенными,Если вы ожидаете стандартный двухбуквенный код страны, например KH, проверьте длину ввода и создайте соответствующий запрос, чтобы избежать ввода OR.country_code должно быть CHAR(2) CHARACTER SET ascii`.

Plan B: Превратить OR в UNION.При исходном запросе вам понадобится 4 SELECTs в UNION.После плана А вы можете обойтись только с 2.

План С: иметь справочную таблицу со всеми вариантами city - прописанными, сокращенными, на китайском и т. Д. Эта таблица будет отображаться наканоническое написание, которое используется в основной таблице.При этом вы избегаете OR для city.

План D: иметь дополнительную колонку TEXT с указанием города, города, страны, страны и всех стран.И, возможно, варианты написания.Индексируйте этот столбец с FULLTEXT.Предостережение: есть проблемы с короткими «словами»;вам, вероятно, следует установить минимальный размер токена 2, чтобы поймать код страны.

0 голосов
/ 01 июня 2018

Предполагая, что столбцы в вашей таблице используют набор символов utf8 и его сопоставление по умолчанию utf8_general_ci:

Вам не нужны вызовы функций LCASE(), поскольку MySQL уже использует сравнения без учета регистра,Измените, например, LCASE(country) = 'cambodia' на country = 'cambodia'.

Сортировка заполняется в индексе, поэтому это эффективно, если индексы присутствуют.

Ваш индекс2 не нужен, поскольку он также содержится в индексе 3.

Запросы с операциями OR, как правило, медленные.Трюки доступны, чтобы ускорить их.

Я не могу сказать, правильны ли ваши индексы.Для этого вам нужно показать свои EXPLAIN результаты и определение вашей таблицы. Прочтите эту заметку о том, как задавать хорошие вопросы по SQL , и обратите внимание на раздел о производительности запросов.

Я бы посоветовал, как изменить определение столбца, но вы не дали нам определение таблицы.

...