php666
@php666
PHP-макака

Можно ли оптимизировать данный запрос или смотреть в сторону денормализации?

Данный SQL запрос имеет различные модификации в коде, но суть одна - он работает на вывод объявлений, с информацией о категории и региональности.

Для наглядности покажу изображение:

e6F1o.png

Вот сам запрос. В нем нет ничего сложного, это JOIN на несколько таблиц и условия в WHERE:

explain SELECT STRAIGHT_JOIN *
    FROM `advert`
    INNER JOIN `user-country` ON `advert`.`advert_place_country` = `user-country`.`id`
    INNER JOIN `user-region` ON `advert`.`advert_place_region` = `user-region`.`id`
    INNER JOIN `user-city` ON `advert`.`advert_place_city` = `user-city`.`id`
    INNER JOIN `user` ON `user`.`id` = `advert`.`advert_id_user`
    INNER JOIN `category` ON `advert`.`advert_category` = `category`.`id`
    WHERE
        `advert_active` = 1 
        AND `advert`.`advert_payment` = 1 
        AND `advert_place_country` = 3159 
        AND `user`.`user_active` = 1
    ORDER BY
        `advert`.`advert_create_date`
    DESC
LIMIT 0, 80


Вот explain:

KZOe9.png

Меня не устраивает время обработки запроса в 0.2 - 0.3 секунды и кол-во затрагиваемых строк. Индекс такой:

`findListForCatalog` (
    `advert_active`,
    `advert_payment`,
    `advert_place_country`,
    `advert_place_region`, // в данном запросе не используется 
    `advert_place_city`    // в данном запросе не используется
)


Сейчас начинаю думать о денормализации данных и создавать триггеры, который будут текстовую информацию региональности и категории (Имя категории, Имя города, региона и страны) писать в таблицу объявлений advert. Таблица разрастется в разы, но иного способа я сейчас уже просто не вижу, перепробовал кучу вариантов. В таблице всего 20 000 записей, но время работы в 0.3 меня совсем не устраивает.
  • Вопрос задан
  • 48 просмотров
Пригласить эксперта
Ответы на вопрос 3
@dimoff66
Кратко о себе: Я есть
Если индексы везде проставлены, то он не должен так долго работать. Для начала локализуйте проблему - попробуйте убрать все джойны и посмотреть за сколько будет обрабатываться без джойнов. Если быстро, то добавляйте постепенно джойны, пока время не станет аномально большим, тогда поймете где затык.

advert_create_date тоже проиндексируйте, если еще нет
Ответ написан
Комментировать
VladimirAndreev
@VladimirAndreev
php web dev
А у вас сортировать по ид нельзя? Обычно более поздние заказы имебт больший ид.
А без индекса по полю сортировки будет полный перебор результата
Ответ написан
Комментировать
@Vitsliputsli
Зачем STRAIGHT_JOIN?
Если в таблице всего 20000 записей, а индекс выбрал 18049, есть ли вообще смысл в таком громоздком составном индексе, если все равно пришлось почти всю таблицу обойти? Вполне может оказаться что без него будет быстрее, или оставить только основной столбец, наиболее различающийся, и столбец для сортировки.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы