#sql #mariadb
Вопрос:
В проекте этот SQL-запрос «насыщает» мой процессор VPS (это небольшой 1-ядерный VPS и 2 ГБ оперативной памяти).
select `orders_super_parents`.`id`, `orders`.`id` as `order_lastUpdatedAt_id`, `orders_dates`.`date_for_stats_filter` as `orderDate__date_for_stats_filter` from `orders_super_parents` inner join `orders` on `orders_super_parents`.`order_id_last_updated_at` = `orders`.`id` inner join `orders_dates` on `orders`.`id` = `orders_dates`.`order_id` where `orders_super_parents`.`deleted_at` is null order by `orders_super_parents`.`row_number` desc limit 15 offset 0
Технологии, которые я использую: PHP 8.0 / Laravel 8 / MariaDB 10.6.
С другой стороны, когда я заменяю строку orders_dates.date_for_stats_filter as orderDate__date_for_stats_filter
(которая является столбцом типа метки времени) на orders_dates.id as orderDate__date_for_stats_filter
(который является простым целочисленным идентификатором), все работает быстро (мои секунды запроса SQL обрабатываются за 0,0024 секунды) вместо 0,5950 секунд, я вижу это при отладке PhpmMyAdmin).
Чтобы попытаться отладить, я выполнил эти 2 SQL-запроса с ОБЪЯСНЕНИЕМ (я сделал скриншоты):
Со столбцом метки orders_dates.date_for_stats_filter
времени (SQL-запрос, который выполняется медленно):
http://www.cms-v2-preprod.daw-dev.fr/medias/app/upload/avec-date_for_stats_filter.png
С целочисленным orders_dates.id
столбцом:
http://www.cms-v2-preprod.daw-dev.fr/medias/app/upload/avec-id.png
Что может быть причиной этого и как я могу это исправить?
Ответ №1:
У вас есть хорошая подсказка-о order_date.
Во-первых, позвольте мне спросить вас, является ли это просто свиданием. Если да, то почему это в отдельной таблице?
Учитывая, что он должен быть отдельным, давайте отложим его получение. В настоящее время вы получаете дату для всех комбинаций двух других таблиц, которые не были «удалены».
SELECT x.id, x.order_lastUpdatedAt_id, od.date_for_stats_filter AS filter_date FROM ( SELECT `sp`.`id`, `orders`.`id` as `order_lastUpdatedAt_id` from `orders_super_parents` AS sp inner join `orders` ON `sp`.`order_id_last_updated_at` = `orders`.`id` where `sp`.`deleted_at` is null order by `sp`.`row_number` desc limit 15 offset 0 ) AS x inner join `orders_dates` AS od ON x.order_lastUpdatedAt_id = `od`.`order_id` order by x.`row_number` desc -- yes, this is repeated
Некоторые индексы:
od: INDEX(order_id, date_for_stats_filter) sp: INDEX(deleted_at, row_number, order_id_last_updated_at, id)
Комментарии:
1. Да, это простая дата (столбец с меткой времени). Я создал специальную таблицу, потому что в ней я храню несколько дат в соответствии с действиями заказов. Выполнение подзапроса в ПЗУ решает мою проблему. Большое спасибо