我正在使用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条答案
按热度按时间bt1cpqcv1#
尝试分页。但是,如果必须一次性显示大量记录,请删除尽可能多的左连接。如果确实需要在一次性结果集中显示,可以复制client\u money\u operation表中的某些数据。
pxyaymoc2#
是一个相当混乱的用法
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
.什么table
operation_code
以及created_at
在哪?它对优化器有很大的影响。但是有一种模式可以用来大大加快查询速度(如果不知道这些列在哪个表中,也不知道是否可以工作,我就无法提供详细信息。)
也就是说,首先(在派生表中)做最少的工作来查找所需的10行的id,然后使用join(s)来获取所需的其他列。
(如果yii2不能生成这样的值,那么它就是一个障碍。)