запрос поставщика данных yii2 занимает очень много времени - PullRequest
0 голосов
/ 16 октября 2018

Я использую провайдер данных yii2 для извлечения данных из базы данных.Необработанный запрос выглядит следующим образом:

 SELECT `client_money_operation`.* FROM `client_money_operation` 
 LEFT JOIN `user` ON `client_money_operation`.`user_id` = `user`.`id` 
 LEFT JOIN `client` ON `client_money_operation`.`client_id` = `client`.`id` 
 LEFT JOIN `client_bonus_operation` ON `client_money_operation`.`id` = `client_bonus_operation`.`money_operation_id` 
 WHERE (`client_money_operation`.`status`=0) AND (`client_money_operation`.`created_at` BETWEEN 1 AND 1539723600) 
 GROUP BY `operation_code` ORDER BY `created_at` DESC LIMIT 10

выполнение этого запроса занимает 107 секунд.Таблица client_money operations содержит 132000 строк.Что мне нужно сделать, чтобы оптимизировать этот запрос или правильно настроить базу данных?

Ответы [ 2 ]

0 голосов
/ 18 октября 2018
SELECT  mo.*
    FROM  `client_money_operation` AS mo
    LEFT JOIN  `user` AS u  ON mo.`user_id` = u.`id`
    LEFT JOIN  `client` AS c  ON mo.`client_id` = c.`id`
    LEFT JOIN  `client_bonus_operation` AS bo  ON mo.`id` = bo.`money_operation_id`
    WHERE  (mo.`status`=0)
      AND  (mo.`created_at` BETWEEN 1 AND 1539723600)
    GROUP BY  `operation_code`
    ORDER BY  `created_at` DESC
    LIMIT  10 

- довольно запутанное использование GROUP BY.Во-первых, неправильно группировать по одному столбцу, имея много неагрегированных столбцов в списке SELECT.И использование created_at в ORDER BY не имеет смысла, так как неясно, какая дата будет связана с каждым operation_code.Возможно, вы хотите MIN(created_at)?

Оптимизация ...

Будет выполнено полное сканирование mo и (надеюсь) PRIMARY KEY поиска в других таблицах.Пожалуйста, укажите EXPLAIN SELECT ..., чтобы мы могли это проверить.

Единственный полезный индекс для mo - это INDEX(status, created_at), и он может или не может быть полезен, в зависимости от того, насколько велик этот диапазон дат.

bo нужен индекс, начинающийся с money_operation_id.

В какие таблицы входят operation_code и created_at?Это имеет значение большое для оптимизатора.

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

SELECT mo.*
    FROM ( SELECT mo.id FROM .. WHERE .. GROUP BY .. ORDER BY .. LIMIT .. ) AS x
    JOIN mo  ON x.id = mo.id
    ORDER BY ..   -- yes, repeated

То есть first do (in aпроизводная таблица) минимальный работает, чтобы найти идентификаторы для 10 требуемых строк, затем используют JOIN (s), чтобы получить другие необходимые столбцы.

(Если yii2 не можетбыть создан, чтобы генерировать такие, тогда это мешает.)

0 голосов
/ 16 октября 2018

Попробуйте нумерацию страниц.Но если вам нужно показать большой набор записей за один раз, удалите как можно больше левых соединений.Вы можете дублировать некоторые данные в таблице client_money_operation, если они, безусловно, должны отображаться в наборе результатов за один раз.

...