对于大型应用程序,我使用以下查询来获取具有关系的所有项目:
$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/