yii2数据提供者查询需要很长时间

7cjasjjr  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(330)

我正在使用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行。我需要做些什么来优化这个查询,或者正确设置我的数据库?

bt1cpqcv

bt1cpqcv1#

尝试分页。但是,如果必须一次性显示大量记录,请删除尽可能多的左连接。如果确实需要在一次性结果集中显示,可以复制client\u money\u operation表中的某些数据。

pxyaymoc

pxyaymoc2#

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_atORDER BY 没有意义,因为不清楚哪一个日期将与每个 operation_code . 也许你想要 MIN(created_at) ?
优化。。。
会有一个完整的扫描 mo 而且(希望如此) PRIMARY KEY 查找其他表。请提供 EXPLAIN SELECT ... 所以我们可以检查一下。
唯一有用的索引 moINDEX(status, created_at) ,它可能有用,也可能无用,这取决于日期范围有多大。 bo 需要一些索引 money_operation_id .
什么table 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

也就是说,首先(在派生表中)做最少的工作来查找所需的10行的id,然后使用join(s)来获取所需的其他列。
(如果yii2不能生成这样的值,那么它就是一个障碍。)

相关问题