Справка по производительности тройного соединения MYSQL, копирование в таблицу Tmp

StackOverflow https://stackoverflow.com/questions/6389429

Вопрос

Я работаю над запросом для новостного сайта, который найдет FeaturedContent для отображения на главной домашней странице. Контент, помеченный таким образом, помечается как «FeaturedContent» и упорядочивается в избранной таблице по «домашней странице». В настоящее время у меня есть желаемый результат, но запрос выполняется более чем за 3 секунды, что мне нужно сократить. Как оптимизировать запрос, подобный следующему?

РЕДАКТИРОВАТЬ: материализовал представление каждую минуту, как предлагается, до 0,4 секунды:

общий

При этом будут упорядочены все функции главной страницы, за которыми следует другой избранный контент, упорядоченный по дате. Объяснение выглядит так:

общий

Профиль выглядит следующим образом:

общий

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

Таблица search_all - это таблица материализованного представления, которая периодически обновляется, а теги и избранные таблицы - это представления. Эти представления не являются обязательными, и их нельзя обойти.

Представление тегов объединяет теги и реляционную таблицу, чтобы получить список тегов в соответствии с item_type и item_id, но все остальные представления представляют собой простые представления одной таблицы.

РЕДАКТИРОВАТЬ: с материализованным представлением самым большим узким местом, по-видимому, является этап «Копирование во временную таблицу». Без заказа вывода это занимает 0,0025 секунды (намного лучше!), Но окончательный вывод все же нужно заказывать. Есть ли способ повысить производительность этого шага или обойти его?

Извините, если форматирование плохо читается, я новичок и не знаю, как это делается регулярно.
Спасибо за вашу помощь! Если что-то еще понадобится, дайте мне знать!

РЕДАКТИРОВАТЬ: размеры таблиц, для справки:
Связи тегов: 197 411
Теги: 16897
Истории: 51 801
Изображения: 28 383
Видео: 2408
Рекомендовано: 13

Это было полезно?

Решение

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

Если у вас есть возможность изменить структуру базы данных, я бы предложил объединить 3 таблицы stories, images и videos в одну, если они, как это выглядит, очень похожи (добавив их в type ENUM('story', 'image', 'video')), чтобы различать записи; это приведет к удалению как подзапроса, так и объединения.

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

Это довольно сложная проблема без знания полной структуры таблицы и перераспределения данных!

Другой вариант, который не предполагает внесения изменений в существующую базу данных (особенно если она уже находится в эксплуатации), - это "кэширование" этой информации в другую таблицу, которая будет периодически обновляться заданием cron.

Кэширование может выполняться на разных уровнях, либо для всего запроса, либо для его частей (независимые представления или 3 объединения, объединенные в одну таблицу кеширования и т. д.)

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top