Высокий процессор с колонкой временных меток

#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. Да, это простая дата (столбец с меткой времени). Я создал специальную таблицу, потому что в ней я храню несколько дат в соответствии с действиями заказов. Выполнение подзапроса в ПЗУ решает мою проблему. Большое спасибо