yii2 数据提供者查询需要很长时间
Posted
技术标签:
【中文标题】yii2 数据提供者查询需要很长时间【英文标题】:yii2 data provider query takes very long time 【发布时间】:2018-10-16 08:57:01 【问题描述】:我正在使用 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 行。我需要做些什么来优化此查询或正确设置我的数据库?
【问题讨论】:
这些表中有索引吗? 【参考方案1】:尝试分页。但是,如果您必须一次显示大量记录,请尽可能多地删除左连接。如果确实需要在一次性结果集中显示,您可以在 client_money_operation 表中复制一些数据。
【讨论】:
【参考方案2】: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
列表中有许多非聚合列时按一列分组是不合适的。并且在ORDER BY
中使用created_at
没有意义,因为不清楚哪个日期将与每个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
也就是说,首先(在派生表中)最少工作以找到所需 10 行的 id,然后使用 JOIN (s) 获取其他所需的列。
(如果 yii2 不能生成这样的,那就是碍事了。)
【讨论】:
以上是关于yii2 数据提供者查询需要很长时间的主要内容,如果未能解决你的问题,请参考以下文章
Android Locationprovider 需要很长时间才能暂时不可用
Android - 获得 GPS 信号需要很长时间。如何实现一个好的 GPS 提供商?