Ускорьте запрос Mysql с помощью 3 левых соединений

#mysql #query-optimization

#mysql #оптимизация запросов

Вопрос:

Я использую следующий запрос с 3 левыми объединениями:

 SELECT `Date`,`Year`,`Month`, `Day`,`Hour`, `Order Line Total` from 

(SELECT order_updated_at, DATE(order_updated_at) as `Date`,  YEAR(order_updated_at) as `Year`, MONTHNAME(order_updated_at) as `Month`, DAYNAME(order_updated_at) as `Day`, order_time_hour_num as `Hour`, orderline_product_id, order_staff_member_id, (orderline_product_total * orderline_product_quantity) AS `Order Line Total` FROM order-lines-table) ORDERS

LEFT JOIN
(SELECT staff_id, first_name, last_name, concat(first_name, ' ', last_name) AS `Staff Member`
FROM staff-table) STAFF
ON ORDERS.order_staff_member_id = STAFF.staff_id

LEFT JOIN
(SELECT * from  
(SELECT category_id, product_id, product_name
FROM products-table group by product_id) PRODUCTS

LEFT JOIN     
(SELECT categories_id, categories_name
FROM categories-table group by categories_id) CATEGORIES
ON PRODUCTS.category_id = CATEGORIES.categories_id) PRODUCTS_AND_CATGORIES

ON ORDERS.orderline_product_id = PRODUCTS_AND_CATGORIES.product_id
  

Для выполнения этого требуется некоторое время (2-3 секунды), что не идеально.

Каждый запрос по отдельности занимает менее 100 мс, но вместе (предположительно из-за соединений) требуется во много раз больше суммы частей для завершения.

Кто-нибудь знает какой-либо способ оптимизировать это, используя другой метод объединений, или это единственный вариант?

Комментарии:

1. Ваша репутация говорит о том, что вы не совсем новичок в Stack Overflow. Вы должны знать, что в вопросах оптимизации запросов вы должны предоставлять SHOW CREATE TABLE выходные данные для каждой таблицы в запросе, чтобы нам не приходилось гадать о типах данных, индексах и ограничениях, которые в настоящее время имеют ваши таблицы.

2. Эй, Билл, извини, я этого не знал, но сделай это сейчас, так что спасибо, что дал мне знать, сделаю это в будущем.

Ответ №1:

Я думаю, что вам не нужны подзапросы в этом случае, когда вы уже используете соединения. Вам не нужна группировка, если я правильно интерпретирую структуру таблицы и данные. Не пробовал, но следующее должно дать тот же результат, что и исходный запрос, но значительно быстрее (и читабельно):

 SELECT 
    DATE(order_updated_at) as `Date`,
    YEAR(order_updated_at) as `Year`,
    MONTHNAME(order_updated_at) as `Month`,
    DAYNAME(order_updated_at) as `Day`,
    order_time_hour_num as `Hour`, 
    (orderline_product_total * orderline_product_quantity) AS `Order Line Total`
FROM order-lines-table olt
LEFT JOIN staff-table st ON olt.order_staff_member_id = st.staff_id
LEFT JOIN products-table pt ON olt.orderline_product_id = pt.product_id
LEFT JOIN categories-table ct ON pt.categories_id = ct.categories_id
  

Комментарии:

1. Вау, это потрясающе, спасибо, определенно узнал что-то новое сегодня!!