晚上好!
我正在开发一个允许Laravel基于MySQL嵌套集模型(lft和rgt键)建立关系的软件包。
图例:X,Y,Z,A,B,C是整数。
我们假设我们想在eshop类别中使用它。
我的第一个任务是创建父关系。我已设法创建一个查找当前类别的父级的关系。我的查询如下:
select * from categories where lft < X and rgt > Y order by lft limit 1
这完全正确。但是,当我想加载时会出现问题,比方说,100个类别。然后,它是100个类别的一个SQL查询:
select * from categories limit 100
和每个类别的父级的一个SQL查询:
select * from categories where lft < X and rgt > Y order by lft desc limit 1
总共 101 sql查询。
这是问题部分的来源。我想使用一种名为Eager Loading的技术(将所有关系查询合并到一个查询中)。但是怎么做呢?
解决方案否。 1
我的第一个解决方案是收集所有lft和rgt键:
select * from categories limit 100
并创建如下所示的查询:
select * from categories where (lft < X or lft < Y or lft < Z ...)
and ( rgt > A or rgt > B or rgt > C ...) order by lft desc
但是,这个解决方案根本不起作用。它返回所有类别的父母。
解决方案否。 2
然后,我尝试使用此方法使其正常工作。原始查询看起来是一样的。
select * from categories limit 100
但加载父母是完全不同的:
(select * from categories where lft < X and rgt > Y order by lft desc limit 1)
union all
(select * from categories where lft < A and rgt > B order by lft desc limit 1)
union all...
此查询仅返回相关结果,这是完美的,但是要向其子项添加父项,我必须运行(在PHP端)foreach循环通过原始查询的所有结果(从类别限制中选择*) 100)并且在foreach内部我必须运行另一个迭代每个父项(来自原始查询)和第二个foreach内部,有一个比较逻辑,它使得10 000(100 * 100)个周期加上比较= looooooooooooong执行
解决方案否。 3
所以我想到了另一个解决方案,这在我看来是最好的。这只是对第二种解决方案的改进。
原始查询:
select * from categories limit 100
关系查询:
(select categories.*, X as child_lft, Y as child_rgt from categories
where lft < X and rgt > Y order by lft desc limit 1)
union all
(select categories.*, A as child_lft, B as child_rgt from categories
where lft < A and rgt > B order by lft desc limit 1)
union all...
所以,现在,在PHP方面,我有一个包含原始查询结果的数组(100个项目)和一个包含关系查询结果的数组(100个项目)。改进之处在于,现在,每个父结果都包含请求它的类别的lft和rgt键(child_lft和child_rgt)。现在,PHP脚本要快得多。首先,我创建一个包含所有父项的新数组(让它命名为$ parents),每个项目键($ parents中值的键)是代码(child_lft.child_rgt =&gt; 1.5),用于标识类别请求它。这是一个循环100次的foreach。第二个foreach遍历原始查询的结果,并检查$ parents数组是否包含一个值,该值包含适合其lft和rgt键的键。所以另外100次迭代。总计,200次迭代=完美!但是关系查询&#39;没有我想要的那么快。
那么,还有另一种方法吗?或者有没有办法如何在解决方案中进行我的SQL查询。 3更快?
感谢您阅读它。谢谢!