Оптимизировать медленный SQL-запрос, используя индексы - PullRequest
0 голосов
/ 10 ноября 2011

У меня проблема с оптимизацией действительно медленного SQL-запроса.Я думаю, что это проблема с индексами, но я не могу найти, какой индекс мне нужно применить.

Это запрос:

SELECT
    cl.ID, cl.title, cl.text, cl.price, cl.URL, cl.ID AS ad_id, cl.cat_id,
    pix.file_name, area.area_name, qn.quarter_name
FROM classifieds cl
/*FORCE INDEX (date_created) */

INNER JOIN classifieds_pix pix ON cl.ID = pix.classified_id AND pix.picture_no = 0
INNER JOIN zip_codes zip ON cl.zip_id = zip.zip_id AND zip.area_id = 132
INNER JOIN area_names area ON zip.area_id = area.id
LEFT JOIN quarter_names qn ON zip.quarter_id = qn.id
WHERE
    cl.confirmed = 1
    AND cl.country = 'DE'
    AND cl.date_created <= NOW() - INTERVAL 1 DAY
ORDER BY
    cl.date_created
desc LIMIT 7

MySQL требуется около 2 секунд, чтобы получить результат,и начать работать в pix.picture_no, но если я выставлю index на «date_created», запрос будет выполняться намного быстрее и займет всего 0,030 с.Но проблема в том, что «INNER JOIN zip_codes ...» не всегда находится в запросе, а когда нет, принудительный индекс снова делает запрос медленным.

Я думал над созданием решенияпо условиям PHP, но хотелось бы знать, в чем проблема с индексами.

Ответы [ 3 ]

0 голосов
/ 10 ноября 2011

Я бы на самом деле имел составной индекс для всех ваших элементов, таких как

(страна, подтверждено, дата создания)

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

0 голосов
/ 02 июля 2017

Вот несколько предложений по оптимизации вашего запроса.

  1. СЕЙЧАС Функция - Вы используете функцию NOW () в предложении WHERE.Вместо этого я рекомендую использовать постоянную дату / время, чтобы позволить значению кэшироваться и оптимизироваться.В противном случае значение NOW () будет оцениваться для каждой строки в предложении WHERE.Альтернативой постоянному значению в случае, если вам нужно динамическое значение, является добавление значения из приложения (например, вычисление текущей метки времени и вставка ее в запрос как константа в приложении перед выполнением запроса. Чтобы проверить эту рекомендациюперед внедрением этого изменения просто замените NOW () на постоянную временную метку и проверьте улучшения производительности.
  2. Индексы - в общем, я бы предложил добавить индекс, содержащий все столбцы вашего WHEREв данном случае: подтверждено, страна, дата_создана. Начните со столбца, в котором будет сокращен объем данных, и продвиньтесь оттуда. Убедитесь, что вы настроили предложение WHERE в том же порядке индекса, в противном случае индекс выигралне будет использоваться.

Я использовал EverSQL SQL Query Optimizer , чтобы получить эти рекомендации (отказ от ответственности: я являюсь соучредителем EverSQL и смиренно предоставляю эти предложения).

0 голосов
/ 10 ноября 2011

Добавьте explain перед запросом и запустите его снова.
Это покажет вам индексы, которые используются.

См .: http://dev.mysql.com/doc/refman/5.0/en/explain.html
И для объяснения explain см .: http://www.slideshare.net/phpcodemonkey/mysql-explain-explained
Или: http://www.databasejournal.com/features/mysql/article.php/1382791/Optimizing-MySQL-Queries-and-Indexes.htm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...