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_codecreated_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 数据提供者查询需要很长时间的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 查询返回 JSON 数据需要很长时间

Android Locationprovider 需要很长时间才能暂时不可用

Android - 获得 GPS 信号需要很长时间。如何实现一个好的 GPS 提供商?

带有recyclerviews的碎片需要很长时间才能加载

将 JSON 数据插入 Core Data 存储需要很长时间

Postgresql 选择计数查询需要很长时间