mysql - Yii2 使用子查询而不是带有 id 的数组进行急切加载

标签 mysql activerecord yii2 database-performance eager-loading

对于大型应用程序,我使用以下查询来获取具有关系的所有项目:

  $project_query = Project::find()->With(['category', 'deliveryTickets', 'garbagePerProjects', 'hourLogs',
        'materialPerProjects', 'employeePerProjects', 'contact', 'invoices'])
        ->where(['project.organization_id' => $this->organization_id]);

它会生成以下查询,例如:

SELECT * FROM `delivery_ticket` WHERE `project_id` IN (124, 137, 147, 148, 149, 219, 222, 241, 1263, 1324, 1325, 1333, 1378, 1423, 1499, 1627, 1687, 1688, 1689, 1690, 1705, 1706, 1962, 2047, 2643, 2774, 2876, 2912, 3005, 3287, 3334, 4251, 4570, 4758, 4963, 5644, 6168, 6605, 6639, 6991, 7000, 7003, 7098, 7530, 7531, 7733, 7734, 7823, 7927, 8452, 8752, 8868, 8903, 8914, 8916, 8917, 8921, 8923, 8931, 8947, 8948, 8949, 8952, 8969, 9042, 9134, 9136, 9137, 9280, 9671, 10262, 10272, 10712, 10730, 11436, 11459, 11520, 11641, 11774, 11776, 12028, 12178, 12323, 12831, 12884, 13050, 13478, 13479, 13595, 13651, 13716, 13946, 14431, 14447, 14523, 15303, 15343, 16269, 16270, 16491, 16513, 17950, 17951)

Mysql解释显示它使用的是range而不是eq_ref

因此我的页面需要 3 秒才能加载。

如何将此查询转换为子查询?

最佳答案

range 在这种情况下是不明确的。要进一步调查,请提供 EXPLAIN SELECT ... 并执行以下步骤:

FLUSH STATUS;
SELECT ...;
SHOW SESSION STATUS LIKE "Handler%";

并查看出现的最大数字。可能的情况:

  • 与表中的行数相同 - 您需要 INDEX(project_id)
  • 与输出中的行数相同(103?)——然后它执行了最佳操作,即跳过表,而不是像它暗示的那样进行一些大的“范围”扫描。至于“3 秒”——这需要更多的思考。
  • 其他一些数字 -- 您运行的是哪个版本? (这可能需要更多调查。)并提供SHOW CREATE TABLE Delivery_ticket

关于mysql - Yii2 使用子查询而不是带有 id 的数组进行急切加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43136516/

相关文章:

mysql - 外键在 MySQL 中不起作用

MySQL - 删除选择

ruby-on-rails - 连接到多个数据库时,ActiveRecord 似乎会泄漏内存

ruby-on-rails - 从两个 id 创建 rails 记录

eloquent - 如何删除yii2中的多对多关系(数据透视表)

mysql - 如何通过mysql对group进行嵌套选择

php - php登录表单验证问题

php - Yii Active Record 在不同表的命名范围内添加多个条件

php - Yii2中如何实现join查询

php - Yii2 - Gii 模型关系 - 为什么函数名称后有 0?